From d9ed6db2f08b9d4895794851b124bc4449fd35b9 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Tue, 9 Apr 2019 09:25:40 +0200 Subject: [PATCH 01/21] Setting up structures --- calypso/api_v4.go | 129 + calypso/proto.go | 1 + calypso/verify.go | 64 + calypso/verify_test.go | 60 + .../epfl/dedis/lib/proto/AuthProxProto.java | 546 +- .../ch/epfl/dedis/lib/proto/ByzCoinProto.java | 2729 ++++---- .../java/ch/epfl/dedis/lib/proto/Calypso.java | 5748 +++++++++++++++-- .../ch/epfl/dedis/lib/proto/DarcProto.java | 926 ++- .../epfl/dedis/lib/proto/EventLogProto.java | 221 +- .../ch/epfl/dedis/lib/proto/NetworkProto.java | 176 +- .../ch/epfl/dedis/lib/proto/OnetProto.java | 86 +- .../ch/epfl/dedis/lib/proto/Personhood.java | 1979 +++--- .../epfl/dedis/lib/proto/SkipchainProto.java | 927 ++- .../ch/epfl/dedis/lib/proto/StatusProto.java | 72 +- .../ch/epfl/dedis/lib/proto/TrieProto.java | 328 +- external/proto/calypso.proto | 61 + proto.sh | 4 +- 17 files changed, 9499 insertions(+), 4558 deletions(-) create mode 100644 calypso/api_v4.go create mode 100644 calypso/verify.go create mode 100644 calypso/verify_test.go diff --git a/calypso/api_v4.go b/calypso/api_v4.go new file mode 100644 index 0000000000..0681786b11 --- /dev/null +++ b/calypso/api_v4.go @@ -0,0 +1,129 @@ +package calypso + +import ( + "time" + + "go.dedis.ch/cothority/v3" + "go.dedis.ch/cothority/v3/byzcoin" + "go.dedis.ch/cothority/v3/skipchain" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/onet/v3" +) + +// TODO: add LTSID of type kyber.Point +// TODO: think about authentication +// TODO: add CreateAndAuthorise +// TODO: add REST interface + +type LTSID kyber.Point + +// ClientV4 is a class to communicate to the calypso service. +type ClientV4 struct { + *onet.Client +} + +// NewClientV4 creates a new client to interact with the Calypso Service. +func NewClientV4() *ClientV4 { + return &ClientV4{Client: onet.NewClient(cothority.Suite, ServiceName)} +} + +// CreateLTS starts a new Distributed Key Generation with the nodes in the roster and +// returns the collective public key X. This X is also used later to identify the +// LTS instance, as there can be more than one LTS group on a node. +// +// It also sets up an authorisation option for the nodes. +// +// This can only be called from localhost, except if the environment variable +// COTHORITY_ALLOW_INSECURE_ADMIN is set to 'true'. +// +// In case of error, X is nil, and the error indicates what is wrong. +// The `sig` returned is a collective signature on the following hash: +// sha256( X | protobuf.Encode(auth) ) +// It can be verified using the aggregate service key from the roster: +// msg := sha256.New() +// Xbuf, err := X.MarshalBinary() +// // Check for errors +// msg.Write(Xbuf) +// authBuf, err := protobuf.Encode(auth) +// // Check for errors +// err = schnorr.Verify(cothority.Suite, roster.ServiceAggregate(calypso.ServiceName), +// msg.Sum(nil), sig) +// // If err == nil, the signature is correct +func (c *ClientV4) CreateLTS(ltsRoster *onet.Roster, auth Auth) (X LTSID, sig []byte, err error) { + return +} + +// Reencrypt requests the re-encryption of the secret stored in the grant. +// The grant must also contain the ephemeral key to which the secret will be +// reencrypted to. +// Finally the grant must contain information about how to verify that the +// reencryption request is valid. +// +// This can be called from anywhere. +// +// If the grant is valid, the reencrypted XHat is returned and err is nil. In case +// of error, XHat is nil, and the error will be returned. +func (c *ClientV4) Reencrypt(X kyber.Point, grant Grant) (XHat kyber.Point, err error) { + return +} + +// +// V4 proposed extensions +// + +// Auth holds all possible authentication structures. When using it to call +// Authorise, only one of the fields must be non-nil. +type Auth struct { + ByzCoin *AuthByzCoin + AuthX509Cert *AuthX509Cert +} + +// AuthByzCoin holds the information necessary to authenticate a byzcoin request. +// In the ByzCoin model, all requests are valid as long as they are stored in the +// blockchain with the given ID. +// The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled. +type AuthByzCoin struct { + ByzCoinID skipchain.SkipBlockID + TTL time.Time +} + +// AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric +// request. In its simplest form, it is simply the CA that will have to sign the +// certificates of the requesters. +// The Threshold indicates how many clients must have signed the request before it +// is accepted. +type AuthX509Cert struct { + // Slice of ASN.1 encoded X509 certificates. + CA [][]byte + Threshold int +} + +// Grant holds one of the possible grant proofs for a reencryption request. Each +// grant proof must hold the secret to be reencrypted, the ephemeral key, as well +// as the proof itself that the request is valid. For each of the authentication +// schemes, this proof will be different. +type Grant struct { + ByzCoin *GrantByzCoin + X509Cert *GrantX509Cert +} + +// GrantByzCoin holds the proof of the write instance, holding the secret itself. +// The proof of the read instance holds the ephemeral key. Both proofs can be +// verified using one of the stored ByzCoinIDs. +type GrantByzCoin struct { + // Write is the proof containing the write request. + Write byzcoin.Proof + // Read is the proof that he has been accepted to read the secret. + Read byzcoin.Proof +} + +// GrantX509Cert holds the proof that at least a threshold number of clients +// accepted the reencryption. +// For each client, there must exist a certificate that can be verified by the +// CA certificate from AuthX509Cert. Additionally, each client must sign the +// following message: +// sha256( Secret | Ephemeral | Time ) +type GrantX509Cert struct { + Secret kyber.Point + Certificates [][]byte +} diff --git a/calypso/proto.go b/calypso/proto.go index fa0ed6701c..fa30d8030e 100644 --- a/calypso/proto.go +++ b/calypso/proto.go @@ -9,6 +9,7 @@ import ( // PROTOSTART // type :skipchain.SkipBlockID:bytes +// type :time.Time:uint64 // package calypso; // import "byzcoin.proto"; // import "onet.proto"; diff --git a/calypso/verify.go b/calypso/verify.go new file mode 100644 index 0000000000..3458414531 --- /dev/null +++ b/calypso/verify.go @@ -0,0 +1,64 @@ +package calypso + +import ( + "crypto/x509" + "crypto/x509/pkix" + "encoding/asn1" + + "golang.org/x/crypto/ed25519" +) + +var ( + // selection of OID numbers is not random See documents + // https://tools.ietf.org/html/rfc5280#page-49 + // https://tools.ietf.org/html/rfc7229 + WriteIdOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 1} + EphemeralKeyOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 2} +) + +func Verify(rootCert *x509.Certificate, toVerify *x509.Certificate) (writeId []byte, key ed25519.PublicKey, err error) { + roots := x509.NewCertPool() + roots.AddCert(rootCert) + + cert, err := x509.ParseCertificate(toVerify.Raw) + if err != nil { + return nil, nil, err + } + + opts := x509.VerifyOptions{ + Roots: roots, + } + + writeIdExt := getExtension(cert, WriteIdOID) + ephemeralKeyExt := getExtension(cert, EphemeralKeyOID) + + unmarkUnhandledCriticalExtension(cert, WriteIdOID) + unmarkUnhandledCriticalExtension(cert, EphemeralKeyOID) + + if _, err := cert.Verify(opts); err != nil { + return nil, nil, err + } + + return writeIdExt.Value, ephemeralKeyExt.Value, nil +} + +func unmarkUnhandledCriticalExtension(cert *x509.Certificate, id asn1.ObjectIdentifier) { + for i, extension := range cert.UnhandledCriticalExtensions { + if id.Equal(extension) { + cert.UnhandledCriticalExtensions = append(cert.UnhandledCriticalExtensions[0:i], + cert.UnhandledCriticalExtensions[i+1:]...) + return + } + } +} + +func getExtension(certificate *x509.Certificate, id asn1.ObjectIdentifier) *pkix.Extension { + + for _, ext := range certificate.Extensions { + if ext.Id.Equal(id) { + return &ext + } + } + + return nil +} diff --git a/calypso/verify_test.go b/calypso/verify_test.go new file mode 100644 index 0000000000..86eb00751b --- /dev/null +++ b/calypso/verify_test.go @@ -0,0 +1,60 @@ +package calypso + +import ( + "crypto/x509" + "encoding/hex" + "encoding/pem" + "errors" + "testing" +) + +const ( + rootCert1 = `-----BEGIN CERTIFICATE----- +MIIB1jCCATigAwIBAgIBATAKBggqhkjOPQQDBDAdMRswGQYDVQQDExJCeXpHZW4g +c2lnbmVyIG9yZzEwHhcNMTkwMzI4MjEwNzUxWhcNNDQwMzIxMjEwNzUxWjAdMRsw +GQYDVQQDExJCeXpHZW4gc2lnbmVyIG9yZzEwgZswEAYHKoZIzj0CAQYFK4EEACMD +gYYABABqdo+aDVte5Fz/xG5Z2GYmIbcVJdXxrMJrTBYgHQafSw0BBKrAyeMcZ534 +/V6eNfkiZa3kuflo6Y2E/NtVxyl7dgFBYTdqvLtPdg7+K7pdj8eKFrAQ0DDi5S0x +aM96oR3S0bU4MIbfMqW1fAsLPw3476Gvju73bfJhEJ3ukx6W2olq+KMmMCQwDgYD +VR0PAQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYIKoZIzj0EAwQDgYsA +MIGHAkEcvPgm0qnXMgpJiOD52VUL3qTwU6uzRYhwIWa3sWCP471/muzsq6PctAEu +CHkpnAlH3DuS2MBBql8ifwwK2PdOGQJCAQcE3+qdiyrABJ315INCTu6HAjpGv0cR +VQWcCmSs80tS9gzvQJ8+peWRuzGvy1Uoyj0qHTSJOHx6z86oOIVbXAIj +-----END CERTIFICATE-----` + + validPem = `-----BEGIN CERTIFICATE----- +MIICKTCCAYqgAwIBAgIQYNsgS2KrQ1ptA7E+cRfiUjAKBggqhkjOPQQDBDAdMRsw +GQYDVQQDExJCeXpHZW4gc2lnbmVyIG9yZzEwHhcNMTkwMzI4MjEwNzUxWhcNMTkw +NDExMjEwNzUxWjAoMSYwJAYDVQQDDB1FcGhlbWVyYWwgcmVhZCBvcGVyYXRpb24g +JiBDbzB2MBAGByqGSM49AgEGBSuBBAAiA2IABPEbevkxsAu3BqZjMBzl+ppSLX1F +4oqnAUxmXx+Yw9mgyunTWzHKPAgHoYmaVDL2a+MDVngmbJI+BiXaZBE00gW854pz +ROa1Z7KxjYGgbRINavXX5nSTbs+xH3w76d3ppKOBgzCBgDAOBgNVHQ8BAf8EBAMC +BSAwDAYDVR0TAQH/BAIwADAvBggrBgEFBQcNAQEB/wQg7PBd8YGomyUmjZpqOy9h +gdAdKEfArphKLRkkozsRRvIwLwYIKwYBBQUHDQIBAf8EIBuJzdwW5DfOVymjPvBM +YXsz+apB9URZnhN1jZy2wrixMAoGCCqGSM49BAMEA4GMADCBiAJCAYwxRrOwCydO +r5KoAndH8/U9nIaM4BWcx1pwYFMM44P0BzXDQgDSYwIAhAQ5hvOpaMPB4IMKI37C +G1lsOKivZEboAkIA90UbyVD7ahZdbpCDKUYAoVejKgA5JAsm8kUGPWt+siw2hsT9 +V/NTETY3evBjoX8kkWs/E5pWpwEGKPQaS25gw1s= +-----END CERTIFICATE-----` +) + +func Test_VerifyCertificateHappyDayScenario(t *testing.T) { + caCert, _ := certFromPem([]byte(rootCert1)) + cert, _ := certFromPem([]byte(validPem)) + + writeId, key, _ := Verify(caCert, cert) + t.Log("writeId", hex.EncodeToString(writeId)) + t.Log("key", hex.EncodeToString(key)) +} + +func certFromPem(pemCerts []byte) (cert *x509.Certificate, err error) { + var block *pem.Block + + block, pemCerts = pem.Decode(pemCerts) + + if block.Type != "CERTIFICATE" { + return nil, errors.New("expected a certificate") + } + + return x509.ParseCertificate(block.Bytes) +} diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/AuthProxProto.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/AuthProxProto.java index 35d8740bf2..975c725ae6 100644 --- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/AuthProxProto.java +++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/AuthProxProto.java @@ -146,7 +146,7 @@ private EnrollRequest( break; } case 26: { - if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + if (!((mutable_bitField0_ & 0x00000004) != 0)) { participants_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000004; } @@ -155,7 +155,7 @@ private EnrollRequest( } case 34: { ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.Builder subBuilder = null; - if (((bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) != 0)) { subBuilder = longpri_.toBuilder(); } longpri_ = input.readMessage(ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.parser(), extensionRegistry); @@ -167,7 +167,7 @@ private EnrollRequest( break; } case 42: { - if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { + if (!((mutable_bitField0_ & 0x00000010) != 0)) { longpubs_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000010; } @@ -189,11 +189,11 @@ private EnrollRequest( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { - if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { - participants_ = java.util.Collections.unmodifiableList(participants_); + if (((mutable_bitField0_ & 0x00000004) != 0)) { + participants_ = java.util.Collections.unmodifiableList(participants_); // C } - if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) { - longpubs_ = java.util.Collections.unmodifiableList(longpubs_); + if (((mutable_bitField0_ & 0x00000010) != 0)) { + longpubs_ = java.util.Collections.unmodifiableList(longpubs_); // C } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); @@ -219,7 +219,7 @@ private EnrollRequest( * required string type = 1; */ public boolean hasType() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** * required string type = 1; @@ -261,7 +261,7 @@ public java.lang.String getType() { * required string issuer = 2; */ public boolean hasIssuer() { - return ((bitField0_ & 0x00000002) == 0x00000002); + return ((bitField0_ & 0x00000002) != 0); } /** * required string issuer = 2; @@ -325,7 +325,7 @@ public com.google.protobuf.ByteString getParticipants(int index) { * required .authprox.PriShare longpri = 4; */ public boolean hasLongpri() { - return ((bitField0_ & 0x00000004) == 0x00000004); + return ((bitField0_ & 0x00000004) != 0); } /** * required .authprox.PriShare longpri = 4; @@ -388,16 +388,16 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { com.google.protobuf.GeneratedMessageV3.writeString(output, 1, type_); } - if (((bitField0_ & 0x00000002) == 0x00000002)) { + if (((bitField0_ & 0x00000002) != 0)) { com.google.protobuf.GeneratedMessageV3.writeString(output, 2, issuer_); } for (int i = 0; i < participants_.size(); i++) { output.writeBytes(3, participants_.get(i)); } - if (((bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) != 0)) { output.writeMessage(4, getLongpri()); } for (int i = 0; i < longpubs_.size(); i++) { @@ -412,10 +412,10 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, type_); } - if (((bitField0_ & 0x00000002) == 0x00000002)) { + if (((bitField0_ & 0x00000002) != 0)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, issuer_); } { @@ -427,7 +427,7 @@ public int getSerializedSize() { size += dataSize; size += 1 * getParticipantsList().size(); } - if (((bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) != 0)) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(4, getLongpri()); } @@ -455,28 +455,27 @@ public boolean equals(final java.lang.Object obj) { } ch.epfl.dedis.lib.proto.AuthProxProto.EnrollRequest other = (ch.epfl.dedis.lib.proto.AuthProxProto.EnrollRequest) obj; - boolean result = true; - result = result && (hasType() == other.hasType()); + if (hasType() != other.hasType()) return false; if (hasType()) { - result = result && getType() - .equals(other.getType()); + if (!getType() + .equals(other.getType())) return false; } - result = result && (hasIssuer() == other.hasIssuer()); + if (hasIssuer() != other.hasIssuer()) return false; if (hasIssuer()) { - result = result && getIssuer() - .equals(other.getIssuer()); + if (!getIssuer() + .equals(other.getIssuer())) return false; } - result = result && getParticipantsList() - .equals(other.getParticipantsList()); - result = result && (hasLongpri() == other.hasLongpri()); + if (!getParticipantsList() + .equals(other.getParticipantsList())) return false; + if (hasLongpri() != other.hasLongpri()) return false; if (hasLongpri()) { - result = result && getLongpri() - .equals(other.getLongpri()); + if (!getLongpri() + .equals(other.getLongpri())) return false; } - result = result && getLongpubsList() - .equals(other.getLongpubsList()); - result = result && unknownFields.equals(other.unknownFields); - return result; + if (!getLongpubsList() + .equals(other.getLongpubsList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; } @java.lang.Override @@ -687,28 +686,28 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.EnrollRequest buildPartial() { ch.epfl.dedis.lib.proto.AuthProxProto.EnrollRequest result = new ch.epfl.dedis.lib.proto.AuthProxProto.EnrollRequest(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + if (((from_bitField0_ & 0x00000001) != 0)) { to_bitField0_ |= 0x00000001; } result.type_ = type_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + if (((from_bitField0_ & 0x00000002) != 0)) { to_bitField0_ |= 0x00000002; } result.issuer_ = issuer_; - if (((bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) != 0)) { participants_ = java.util.Collections.unmodifiableList(participants_); bitField0_ = (bitField0_ & ~0x00000004); } result.participants_ = participants_; - if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + if (((from_bitField0_ & 0x00000008) != 0)) { + if (longpriBuilder_ == null) { + result.longpri_ = longpri_; + } else { + result.longpri_ = longpriBuilder_.build(); + } to_bitField0_ |= 0x00000004; } - if (longpriBuilder_ == null) { - result.longpri_ = longpri_; - } else { - result.longpri_ = longpriBuilder_.build(); - } - if (((bitField0_ & 0x00000010) == 0x00000010)) { + if (((bitField0_ & 0x00000010) != 0)) { longpubs_ = java.util.Collections.unmodifiableList(longpubs_); bitField0_ = (bitField0_ & ~0x00000010); } @@ -720,35 +719,35 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.EnrollRequest buildPartial() { @java.lang.Override public Builder clone() { - return (Builder) super.clone(); + return super.clone(); } @java.lang.Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.setField(field, value); + return super.setField(field, value); } @java.lang.Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { - return (Builder) super.clearField(field); + return super.clearField(field); } @java.lang.Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return (Builder) super.clearOneof(oneof); + return super.clearOneof(oneof); } @java.lang.Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { - return (Builder) super.setRepeatedField(field, index, value); + return super.setRepeatedField(field, index, value); } @java.lang.Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.addRepeatedField(field, value); + return super.addRepeatedField(field, value); } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { @@ -839,7 +838,7 @@ public Builder mergeFrom( * required string type = 1; */ public boolean hasType() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** * required string type = 1; @@ -915,7 +914,7 @@ public Builder setTypeBytes( * required string issuer = 2; */ public boolean hasIssuer() { - return ((bitField0_ & 0x00000002) == 0x00000002); + return ((bitField0_ & 0x00000002) != 0); } /** * required string issuer = 2; @@ -988,7 +987,7 @@ public Builder setIssuerBytes( private java.util.List participants_ = java.util.Collections.emptyList(); private void ensureParticipantsIsMutable() { - if (!((bitField0_ & 0x00000004) == 0x00000004)) { + if (!((bitField0_ & 0x00000004) != 0)) { participants_ = new java.util.ArrayList(participants_); bitField0_ |= 0x00000004; } @@ -998,7 +997,8 @@ private void ensureParticipantsIsMutable() { */ public java.util.List getParticipantsList() { - return java.util.Collections.unmodifiableList(participants_); + return ((bitField0_ & 0x00000004) != 0) ? + java.util.Collections.unmodifiableList(participants_) : participants_; } /** * repeated bytes participants = 3; @@ -1058,14 +1058,14 @@ public Builder clearParticipants() { return this; } - private ch.epfl.dedis.lib.proto.AuthProxProto.PriShare longpri_ = null; + private ch.epfl.dedis.lib.proto.AuthProxProto.PriShare longpri_; private com.google.protobuf.SingleFieldBuilderV3< ch.epfl.dedis.lib.proto.AuthProxProto.PriShare, ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.Builder, ch.epfl.dedis.lib.proto.AuthProxProto.PriShareOrBuilder> longpriBuilder_; /** * required .authprox.PriShare longpri = 4; */ public boolean hasLongpri() { - return ((bitField0_ & 0x00000008) == 0x00000008); + return ((bitField0_ & 0x00000008) != 0); } /** * required .authprox.PriShare longpri = 4; @@ -1112,7 +1112,7 @@ public Builder setLongpri( */ public Builder mergeLongpri(ch.epfl.dedis.lib.proto.AuthProxProto.PriShare value) { if (longpriBuilder_ == null) { - if (((bitField0_ & 0x00000008) == 0x00000008) && + if (((bitField0_ & 0x00000008) != 0) && longpri_ != null && longpri_ != ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.getDefaultInstance()) { longpri_ = @@ -1178,7 +1178,7 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.PriShareOrBuilder getLongpriOrBuild private java.util.List longpubs_ = java.util.Collections.emptyList(); private void ensureLongpubsIsMutable() { - if (!((bitField0_ & 0x00000010) == 0x00000010)) { + if (!((bitField0_ & 0x00000010) != 0)) { longpubs_ = new java.util.ArrayList(longpubs_); bitField0_ |= 0x00000010; } @@ -1188,7 +1188,8 @@ private void ensureLongpubsIsMutable() { */ public java.util.List getLongpubsList() { - return java.util.Collections.unmodifiableList(longpubs_); + return ((bitField0_ & 0x00000010) != 0) ? + java.util.Collections.unmodifiableList(longpubs_) : longpubs_; } /** * repeated bytes longpubs = 5; @@ -1416,9 +1417,8 @@ public boolean equals(final java.lang.Object obj) { } ch.epfl.dedis.lib.proto.AuthProxProto.EnrollResponse other = (ch.epfl.dedis.lib.proto.AuthProxProto.EnrollResponse) obj; - boolean result = true; - result = result && unknownFields.equals(other.unknownFields); - return result; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; } @java.lang.Override @@ -1597,35 +1597,35 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.EnrollResponse buildPartial() { @java.lang.Override public Builder clone() { - return (Builder) super.clone(); + return super.clone(); } @java.lang.Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.setField(field, value); + return super.setField(field, value); } @java.lang.Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { - return (Builder) super.clearField(field); + return super.clearField(field); } @java.lang.Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return (Builder) super.clearOneof(oneof); + return super.clearOneof(oneof); } @java.lang.Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { - return (Builder) super.setRepeatedField(field, index, value); + return super.setRepeatedField(field, index, value); } @java.lang.Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.addRepeatedField(field, value); + return super.addRepeatedField(field, value); } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { @@ -1866,7 +1866,7 @@ private SignatureRequest( } case 34: { ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.Builder subBuilder = null; - if (((bitField0_ & 0x00000008) == 0x00000008)) { + if (((bitField0_ & 0x00000008) != 0)) { subBuilder = randpri_.toBuilder(); } randpri_ = input.readMessage(ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.parser(), extensionRegistry); @@ -1878,7 +1878,7 @@ private SignatureRequest( break; } case 42: { - if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { + if (!((mutable_bitField0_ & 0x00000010) != 0)) { randpubs_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000010; } @@ -1905,8 +1905,8 @@ private SignatureRequest( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { - if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) { - randpubs_ = java.util.Collections.unmodifiableList(randpubs_); + if (((mutable_bitField0_ & 0x00000010) != 0)) { + randpubs_ = java.util.Collections.unmodifiableList(randpubs_); // C } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); @@ -1932,7 +1932,7 @@ private SignatureRequest( * required string type = 1; */ public boolean hasType() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** * required string type = 1; @@ -1974,7 +1974,7 @@ public java.lang.String getType() { * required string issuer = 2; */ public boolean hasIssuer() { - return ((bitField0_ & 0x00000002) == 0x00000002); + return ((bitField0_ & 0x00000002) != 0); } /** * required string issuer = 2; @@ -2016,7 +2016,7 @@ public java.lang.String getIssuer() { * required bytes authinfo = 3; */ public boolean hasAuthinfo() { - return ((bitField0_ & 0x00000004) == 0x00000004); + return ((bitField0_ & 0x00000004) != 0); } /** * required bytes authinfo = 3; @@ -2031,7 +2031,7 @@ public com.google.protobuf.ByteString getAuthinfo() { * required .authprox.PriShare randpri = 4; */ public boolean hasRandpri() { - return ((bitField0_ & 0x00000008) == 0x00000008); + return ((bitField0_ & 0x00000008) != 0); } /** * required .authprox.PriShare randpri = 4; @@ -2074,7 +2074,7 @@ public com.google.protobuf.ByteString getRandpubs(int index) { * required bytes message = 6; */ public boolean hasMessage() { - return ((bitField0_ & 0x00000010) == 0x00000010); + return ((bitField0_ & 0x00000010) != 0); } /** * required bytes message = 6; @@ -2117,22 +2117,22 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { com.google.protobuf.GeneratedMessageV3.writeString(output, 1, type_); } - if (((bitField0_ & 0x00000002) == 0x00000002)) { + if (((bitField0_ & 0x00000002) != 0)) { com.google.protobuf.GeneratedMessageV3.writeString(output, 2, issuer_); } - if (((bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) != 0)) { output.writeBytes(3, authinfo_); } - if (((bitField0_ & 0x00000008) == 0x00000008)) { + if (((bitField0_ & 0x00000008) != 0)) { output.writeMessage(4, getRandpri()); } for (int i = 0; i < randpubs_.size(); i++) { output.writeBytes(5, randpubs_.get(i)); } - if (((bitField0_ & 0x00000010) == 0x00000010)) { + if (((bitField0_ & 0x00000010) != 0)) { output.writeBytes(6, message_); } unknownFields.writeTo(output); @@ -2144,17 +2144,17 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, type_); } - if (((bitField0_ & 0x00000002) == 0x00000002)) { + if (((bitField0_ & 0x00000002) != 0)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, issuer_); } - if (((bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) != 0)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(3, authinfo_); } - if (((bitField0_ & 0x00000008) == 0x00000008)) { + if (((bitField0_ & 0x00000008) != 0)) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(4, getRandpri()); } @@ -2167,7 +2167,7 @@ public int getSerializedSize() { size += dataSize; size += 1 * getRandpubsList().size(); } - if (((bitField0_ & 0x00000010) == 0x00000010)) { + if (((bitField0_ & 0x00000010) != 0)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(6, message_); } @@ -2186,36 +2186,35 @@ public boolean equals(final java.lang.Object obj) { } ch.epfl.dedis.lib.proto.AuthProxProto.SignatureRequest other = (ch.epfl.dedis.lib.proto.AuthProxProto.SignatureRequest) obj; - boolean result = true; - result = result && (hasType() == other.hasType()); + if (hasType() != other.hasType()) return false; if (hasType()) { - result = result && getType() - .equals(other.getType()); + if (!getType() + .equals(other.getType())) return false; } - result = result && (hasIssuer() == other.hasIssuer()); + if (hasIssuer() != other.hasIssuer()) return false; if (hasIssuer()) { - result = result && getIssuer() - .equals(other.getIssuer()); + if (!getIssuer() + .equals(other.getIssuer())) return false; } - result = result && (hasAuthinfo() == other.hasAuthinfo()); + if (hasAuthinfo() != other.hasAuthinfo()) return false; if (hasAuthinfo()) { - result = result && getAuthinfo() - .equals(other.getAuthinfo()); + if (!getAuthinfo() + .equals(other.getAuthinfo())) return false; } - result = result && (hasRandpri() == other.hasRandpri()); + if (hasRandpri() != other.hasRandpri()) return false; if (hasRandpri()) { - result = result && getRandpri() - .equals(other.getRandpri()); + if (!getRandpri() + .equals(other.getRandpri())) return false; } - result = result && getRandpubsList() - .equals(other.getRandpubsList()); - result = result && (hasMessage() == other.hasMessage()); + if (!getRandpubsList() + .equals(other.getRandpubsList())) return false; + if (hasMessage() != other.hasMessage()) return false; if (hasMessage()) { - result = result && getMessage() - .equals(other.getMessage()); + if (!getMessage() + .equals(other.getMessage())) return false; } - result = result && unknownFields.equals(other.unknownFields); - return result; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; } @java.lang.Override @@ -2434,32 +2433,32 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.SignatureRequest buildPartial() { ch.epfl.dedis.lib.proto.AuthProxProto.SignatureRequest result = new ch.epfl.dedis.lib.proto.AuthProxProto.SignatureRequest(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + if (((from_bitField0_ & 0x00000001) != 0)) { to_bitField0_ |= 0x00000001; } result.type_ = type_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + if (((from_bitField0_ & 0x00000002) != 0)) { to_bitField0_ |= 0x00000002; } result.issuer_ = issuer_; - if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + if (((from_bitField0_ & 0x00000004) != 0)) { to_bitField0_ |= 0x00000004; } result.authinfo_ = authinfo_; - if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + if (((from_bitField0_ & 0x00000008) != 0)) { + if (randpriBuilder_ == null) { + result.randpri_ = randpri_; + } else { + result.randpri_ = randpriBuilder_.build(); + } to_bitField0_ |= 0x00000008; } - if (randpriBuilder_ == null) { - result.randpri_ = randpri_; - } else { - result.randpri_ = randpriBuilder_.build(); - } - if (((bitField0_ & 0x00000010) == 0x00000010)) { + if (((bitField0_ & 0x00000010) != 0)) { randpubs_ = java.util.Collections.unmodifiableList(randpubs_); bitField0_ = (bitField0_ & ~0x00000010); } result.randpubs_ = randpubs_; - if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + if (((from_bitField0_ & 0x00000020) != 0)) { to_bitField0_ |= 0x00000010; } result.message_ = message_; @@ -2470,35 +2469,35 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.SignatureRequest buildPartial() { @java.lang.Override public Builder clone() { - return (Builder) super.clone(); + return super.clone(); } @java.lang.Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.setField(field, value); + return super.setField(field, value); } @java.lang.Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { - return (Builder) super.clearField(field); + return super.clearField(field); } @java.lang.Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return (Builder) super.clearOneof(oneof); + return super.clearOneof(oneof); } @java.lang.Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { - return (Builder) super.setRepeatedField(field, index, value); + return super.setRepeatedField(field, index, value); } @java.lang.Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.addRepeatedField(field, value); + return super.addRepeatedField(field, value); } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { @@ -2591,7 +2590,7 @@ public Builder mergeFrom( * required string type = 1; */ public boolean hasType() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** * required string type = 1; @@ -2667,7 +2666,7 @@ public Builder setTypeBytes( * required string issuer = 2; */ public boolean hasIssuer() { - return ((bitField0_ & 0x00000002) == 0x00000002); + return ((bitField0_ & 0x00000002) != 0); } /** * required string issuer = 2; @@ -2743,7 +2742,7 @@ public Builder setIssuerBytes( * required bytes authinfo = 3; */ public boolean hasAuthinfo() { - return ((bitField0_ & 0x00000004) == 0x00000004); + return ((bitField0_ & 0x00000004) != 0); } /** * required bytes authinfo = 3; @@ -2773,14 +2772,14 @@ public Builder clearAuthinfo() { return this; } - private ch.epfl.dedis.lib.proto.AuthProxProto.PriShare randpri_ = null; + private ch.epfl.dedis.lib.proto.AuthProxProto.PriShare randpri_; private com.google.protobuf.SingleFieldBuilderV3< ch.epfl.dedis.lib.proto.AuthProxProto.PriShare, ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.Builder, ch.epfl.dedis.lib.proto.AuthProxProto.PriShareOrBuilder> randpriBuilder_; /** * required .authprox.PriShare randpri = 4; */ public boolean hasRandpri() { - return ((bitField0_ & 0x00000008) == 0x00000008); + return ((bitField0_ & 0x00000008) != 0); } /** * required .authprox.PriShare randpri = 4; @@ -2827,7 +2826,7 @@ public Builder setRandpri( */ public Builder mergeRandpri(ch.epfl.dedis.lib.proto.AuthProxProto.PriShare value) { if (randpriBuilder_ == null) { - if (((bitField0_ & 0x00000008) == 0x00000008) && + if (((bitField0_ & 0x00000008) != 0) && randpri_ != null && randpri_ != ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.getDefaultInstance()) { randpri_ = @@ -2893,7 +2892,7 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.PriShareOrBuilder getRandpriOrBuild private java.util.List randpubs_ = java.util.Collections.emptyList(); private void ensureRandpubsIsMutable() { - if (!((bitField0_ & 0x00000010) == 0x00000010)) { + if (!((bitField0_ & 0x00000010) != 0)) { randpubs_ = new java.util.ArrayList(randpubs_); bitField0_ |= 0x00000010; } @@ -2903,7 +2902,8 @@ private void ensureRandpubsIsMutable() { */ public java.util.List getRandpubsList() { - return java.util.Collections.unmodifiableList(randpubs_); + return ((bitField0_ & 0x00000010) != 0) ? + java.util.Collections.unmodifiableList(randpubs_) : randpubs_; } /** * repeated bytes randpubs = 5; @@ -2968,7 +2968,7 @@ public Builder clearRandpubs() { * required bytes message = 6; */ public boolean hasMessage() { - return ((bitField0_ & 0x00000020) == 0x00000020); + return ((bitField0_ & 0x00000020) != 0); } /** * required bytes message = 6; @@ -3167,9 +3167,8 @@ public boolean equals(final java.lang.Object obj) { } ch.epfl.dedis.lib.proto.AuthProxProto.PriShare other = (ch.epfl.dedis.lib.proto.AuthProxProto.PriShare) obj; - boolean result = true; - result = result && unknownFields.equals(other.unknownFields); - return result; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; } @java.lang.Override @@ -3349,35 +3348,35 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.PriShare buildPartial() { @java.lang.Override public Builder clone() { - return (Builder) super.clone(); + return super.clone(); } @java.lang.Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.setField(field, value); + return super.setField(field, value); } @java.lang.Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { - return (Builder) super.clearField(field); + return super.clearField(field); } @java.lang.Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return (Builder) super.clearOneof(oneof); + return super.clearOneof(oneof); } @java.lang.Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { - return (Builder) super.setRepeatedField(field, index, value); + return super.setRepeatedField(field, index, value); } @java.lang.Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.addRepeatedField(field, value); + return super.addRepeatedField(field, value); } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { @@ -3555,7 +3554,7 @@ private PartialSig( break; case 10: { ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.Builder subBuilder = null; - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { subBuilder = partial_.toBuilder(); } partial_ = input.readMessage(ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.parser(), extensionRegistry); @@ -3615,7 +3614,7 @@ private PartialSig( * required .authprox.PriShare partial = 1; */ public boolean hasPartial() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** * required .authprox.PriShare partial = 1; @@ -3636,7 +3635,7 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.PriShareOrBuilder getPartialOrBuild * required bytes sessionid = 2; */ public boolean hasSessionid() { - return ((bitField0_ & 0x00000002) == 0x00000002); + return ((bitField0_ & 0x00000002) != 0); } /** * required bytes sessionid = 2; @@ -3651,7 +3650,7 @@ public com.google.protobuf.ByteString getSessionid() { * required bytes signature = 3; */ public boolean hasSignature() { - return ((bitField0_ & 0x00000004) == 0x00000004); + return ((bitField0_ & 0x00000004) != 0); } /** * required bytes signature = 3; @@ -3686,13 +3685,13 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { output.writeMessage(1, getPartial()); } - if (((bitField0_ & 0x00000002) == 0x00000002)) { + if (((bitField0_ & 0x00000002) != 0)) { output.writeBytes(2, sessionid_); } - if (((bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) != 0)) { output.writeBytes(3, signature_); } unknownFields.writeTo(output); @@ -3704,15 +3703,15 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(1, getPartial()); } - if (((bitField0_ & 0x00000002) == 0x00000002)) { + if (((bitField0_ & 0x00000002) != 0)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(2, sessionid_); } - if (((bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) != 0)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(3, signature_); } @@ -3731,24 +3730,23 @@ public boolean equals(final java.lang.Object obj) { } ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig other = (ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig) obj; - boolean result = true; - result = result && (hasPartial() == other.hasPartial()); + if (hasPartial() != other.hasPartial()) return false; if (hasPartial()) { - result = result && getPartial() - .equals(other.getPartial()); + if (!getPartial() + .equals(other.getPartial())) return false; } - result = result && (hasSessionid() == other.hasSessionid()); + if (hasSessionid() != other.hasSessionid()) return false; if (hasSessionid()) { - result = result && getSessionid() - .equals(other.getSessionid()); + if (!getSessionid() + .equals(other.getSessionid())) return false; } - result = result && (hasSignature() == other.hasSignature()); + if (hasSignature() != other.hasSignature()) return false; if (hasSignature()) { - result = result && getSignature() - .equals(other.getSignature()); + if (!getSignature() + .equals(other.getSignature())) return false; } - result = result && unknownFields.equals(other.unknownFields); - return result; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; } @java.lang.Override @@ -3947,19 +3945,19 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig buildPartial() { ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig result = new ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + if (((from_bitField0_ & 0x00000001) != 0)) { + if (partialBuilder_ == null) { + result.partial_ = partial_; + } else { + result.partial_ = partialBuilder_.build(); + } to_bitField0_ |= 0x00000001; } - if (partialBuilder_ == null) { - result.partial_ = partial_; - } else { - result.partial_ = partialBuilder_.build(); - } - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + if (((from_bitField0_ & 0x00000002) != 0)) { to_bitField0_ |= 0x00000002; } result.sessionid_ = sessionid_; - if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + if (((from_bitField0_ & 0x00000004) != 0)) { to_bitField0_ |= 0x00000004; } result.signature_ = signature_; @@ -3970,35 +3968,35 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig buildPartial() { @java.lang.Override public Builder clone() { - return (Builder) super.clone(); + return super.clone(); } @java.lang.Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.setField(field, value); + return super.setField(field, value); } @java.lang.Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { - return (Builder) super.clearField(field); + return super.clearField(field); } @java.lang.Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return (Builder) super.clearOneof(oneof); + return super.clearOneof(oneof); } @java.lang.Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { - return (Builder) super.setRepeatedField(field, index, value); + return super.setRepeatedField(field, index, value); } @java.lang.Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.addRepeatedField(field, value); + return super.addRepeatedField(field, value); } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { @@ -4060,14 +4058,14 @@ public Builder mergeFrom( } private int bitField0_; - private ch.epfl.dedis.lib.proto.AuthProxProto.PriShare partial_ = null; + private ch.epfl.dedis.lib.proto.AuthProxProto.PriShare partial_; private com.google.protobuf.SingleFieldBuilderV3< ch.epfl.dedis.lib.proto.AuthProxProto.PriShare, ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.Builder, ch.epfl.dedis.lib.proto.AuthProxProto.PriShareOrBuilder> partialBuilder_; /** * required .authprox.PriShare partial = 1; */ public boolean hasPartial() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** * required .authprox.PriShare partial = 1; @@ -4114,7 +4112,7 @@ public Builder setPartial( */ public Builder mergePartial(ch.epfl.dedis.lib.proto.AuthProxProto.PriShare value) { if (partialBuilder_ == null) { - if (((bitField0_ & 0x00000001) == 0x00000001) && + if (((bitField0_ & 0x00000001) != 0) && partial_ != null && partial_ != ch.epfl.dedis.lib.proto.AuthProxProto.PriShare.getDefaultInstance()) { partial_ = @@ -4183,7 +4181,7 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.PriShareOrBuilder getPartialOrBuild * required bytes sessionid = 2; */ public boolean hasSessionid() { - return ((bitField0_ & 0x00000002) == 0x00000002); + return ((bitField0_ & 0x00000002) != 0); } /** * required bytes sessionid = 2; @@ -4218,7 +4216,7 @@ public Builder clearSessionid() { * required bytes signature = 3; */ public boolean hasSignature() { - return ((bitField0_ & 0x00000004) == 0x00000004); + return ((bitField0_ & 0x00000004) != 0); } /** * required bytes signature = 3; @@ -4362,7 +4360,7 @@ private SignatureResponse( break; case 10: { ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig.Builder subBuilder = null; - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { subBuilder = partialsignature_.toBuilder(); } partialsignature_ = input.readMessage(ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig.parser(), extensionRegistry); @@ -4412,7 +4410,7 @@ private SignatureResponse( * required .authprox.PartialSig partialsignature = 1; */ public boolean hasPartialsignature() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** * required .authprox.PartialSig partialsignature = 1; @@ -4449,7 +4447,7 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { output.writeMessage(1, getPartialsignature()); } unknownFields.writeTo(output); @@ -4461,7 +4459,7 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(1, getPartialsignature()); } @@ -4480,14 +4478,13 @@ public boolean equals(final java.lang.Object obj) { } ch.epfl.dedis.lib.proto.AuthProxProto.SignatureResponse other = (ch.epfl.dedis.lib.proto.AuthProxProto.SignatureResponse) obj; - boolean result = true; - result = result && (hasPartialsignature() == other.hasPartialsignature()); + if (hasPartialsignature() != other.hasPartialsignature()) return false; if (hasPartialsignature()) { - result = result && getPartialsignature() - .equals(other.getPartialsignature()); + if (!getPartialsignature() + .equals(other.getPartialsignature())) return false; } - result = result && unknownFields.equals(other.unknownFields); - return result; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; } @java.lang.Override @@ -4673,14 +4670,14 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.SignatureResponse buildPartial() { ch.epfl.dedis.lib.proto.AuthProxProto.SignatureResponse result = new ch.epfl.dedis.lib.proto.AuthProxProto.SignatureResponse(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + if (((from_bitField0_ & 0x00000001) != 0)) { + if (partialsignatureBuilder_ == null) { + result.partialsignature_ = partialsignature_; + } else { + result.partialsignature_ = partialsignatureBuilder_.build(); + } to_bitField0_ |= 0x00000001; } - if (partialsignatureBuilder_ == null) { - result.partialsignature_ = partialsignature_; - } else { - result.partialsignature_ = partialsignatureBuilder_.build(); - } result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -4688,35 +4685,35 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.SignatureResponse buildPartial() { @java.lang.Override public Builder clone() { - return (Builder) super.clone(); + return super.clone(); } @java.lang.Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.setField(field, value); + return super.setField(field, value); } @java.lang.Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { - return (Builder) super.clearField(field); + return super.clearField(field); } @java.lang.Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return (Builder) super.clearOneof(oneof); + return super.clearOneof(oneof); } @java.lang.Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { - return (Builder) super.setRepeatedField(field, index, value); + return super.setRepeatedField(field, index, value); } @java.lang.Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.addRepeatedField(field, value); + return super.addRepeatedField(field, value); } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { @@ -4769,14 +4766,14 @@ public Builder mergeFrom( } private int bitField0_; - private ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig partialsignature_ = null; + private ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig partialsignature_; private com.google.protobuf.SingleFieldBuilderV3< ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig, ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig.Builder, ch.epfl.dedis.lib.proto.AuthProxProto.PartialSigOrBuilder> partialsignatureBuilder_; /** * required .authprox.PartialSig partialsignature = 1; */ public boolean hasPartialsignature() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** * required .authprox.PartialSig partialsignature = 1; @@ -4823,7 +4820,7 @@ public Builder setPartialsignature( */ public Builder mergePartialsignature(ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig value) { if (partialsignatureBuilder_ == null) { - if (((bitField0_ & 0x00000001) == 0x00000001) && + if (((bitField0_ & 0x00000001) != 0) && partialsignature_ != null && partialsignature_ != ch.epfl.dedis.lib.proto.AuthProxProto.PartialSig.getDefaultInstance()) { partialsignature_ = @@ -5031,7 +5028,7 @@ private EnrollmentsRequest( break; case 10: { com.google.protobuf.ByteString bs = input.readBytes(); - if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { types_ = new com.google.protobuf.LazyStringArrayList(); mutable_bitField0_ |= 0x00000001; } @@ -5040,7 +5037,7 @@ private EnrollmentsRequest( } case 18: { com.google.protobuf.ByteString bs = input.readBytes(); - if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + if (!((mutable_bitField0_ & 0x00000002) != 0)) { issuers_ = new com.google.protobuf.LazyStringArrayList(); mutable_bitField0_ |= 0x00000002; } @@ -5062,10 +5059,10 @@ private EnrollmentsRequest( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { - if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + if (((mutable_bitField0_ & 0x00000001) != 0)) { types_ = types_.getUnmodifiableView(); } - if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + if (((mutable_bitField0_ & 0x00000002) != 0)) { issuers_ = issuers_.getUnmodifiableView(); } this.unknownFields = unknownFields.build(); @@ -5203,13 +5200,12 @@ public boolean equals(final java.lang.Object obj) { } ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsRequest other = (ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsRequest) obj; - boolean result = true; - result = result && getTypesList() - .equals(other.getTypesList()); - result = result && getIssuersList() - .equals(other.getIssuersList()); - result = result && unknownFields.equals(other.unknownFields); - return result; + if (!getTypesList() + .equals(other.getTypesList())) return false; + if (!getIssuersList() + .equals(other.getIssuersList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; } @java.lang.Override @@ -5398,12 +5394,12 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsRequest build() { public ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsRequest buildPartial() { ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsRequest result = new ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsRequest(this); int from_bitField0_ = bitField0_; - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { types_ = types_.getUnmodifiableView(); bitField0_ = (bitField0_ & ~0x00000001); } result.types_ = types_; - if (((bitField0_ & 0x00000002) == 0x00000002)) { + if (((bitField0_ & 0x00000002) != 0)) { issuers_ = issuers_.getUnmodifiableView(); bitField0_ = (bitField0_ & ~0x00000002); } @@ -5414,35 +5410,35 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsRequest buildPartial() { @java.lang.Override public Builder clone() { - return (Builder) super.clone(); + return super.clone(); } @java.lang.Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.setField(field, value); + return super.setField(field, value); } @java.lang.Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { - return (Builder) super.clearField(field); + return super.clearField(field); } @java.lang.Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return (Builder) super.clearOneof(oneof); + return super.clearOneof(oneof); } @java.lang.Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { - return (Builder) super.setRepeatedField(field, index, value); + return super.setRepeatedField(field, index, value); } @java.lang.Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.addRepeatedField(field, value); + return super.addRepeatedField(field, value); } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { @@ -5508,7 +5504,7 @@ public Builder mergeFrom( private com.google.protobuf.LazyStringList types_ = com.google.protobuf.LazyStringArrayList.EMPTY; private void ensureTypesIsMutable() { - if (!((bitField0_ & 0x00000001) == 0x00000001)) { + if (!((bitField0_ & 0x00000001) != 0)) { types_ = new com.google.protobuf.LazyStringArrayList(types_); bitField0_ |= 0x00000001; } @@ -5601,7 +5597,7 @@ public Builder addTypesBytes( private com.google.protobuf.LazyStringList issuers_ = com.google.protobuf.LazyStringArrayList.EMPTY; private void ensureIssuersIsMutable() { - if (!((bitField0_ & 0x00000002) == 0x00000002)) { + if (!((bitField0_ & 0x00000002) != 0)) { issuers_ = new com.google.protobuf.LazyStringArrayList(issuers_); bitField0_ |= 0x00000002; } @@ -5817,7 +5813,7 @@ private EnrollmentsResponse( done = true; break; case 10: { - if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { enrollments_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000001; } @@ -5840,7 +5836,7 @@ private EnrollmentsResponse( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { - if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + if (((mutable_bitField0_ & 0x00000001) != 0)) { enrollments_ = java.util.Collections.unmodifiableList(enrollments_); } this.unknownFields = unknownFields.build(); @@ -5946,11 +5942,10 @@ public boolean equals(final java.lang.Object obj) { } ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsResponse other = (ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsResponse) obj; - boolean result = true; - result = result && getEnrollmentsList() - .equals(other.getEnrollmentsList()); - result = result && unknownFields.equals(other.unknownFields); - return result; + if (!getEnrollmentsList() + .equals(other.getEnrollmentsList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; } @java.lang.Override @@ -6136,7 +6131,7 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsResponse buildPartial() ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsResponse result = new ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsResponse(this); int from_bitField0_ = bitField0_; if (enrollmentsBuilder_ == null) { - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { enrollments_ = java.util.Collections.unmodifiableList(enrollments_); bitField0_ = (bitField0_ & ~0x00000001); } @@ -6150,35 +6145,35 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentsResponse buildPartial() @java.lang.Override public Builder clone() { - return (Builder) super.clone(); + return super.clone(); } @java.lang.Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.setField(field, value); + return super.setField(field, value); } @java.lang.Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { - return (Builder) super.clearField(field); + return super.clearField(field); } @java.lang.Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return (Builder) super.clearOneof(oneof); + return super.clearOneof(oneof); } @java.lang.Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { - return (Builder) super.setRepeatedField(field, index, value); + return super.setRepeatedField(field, index, value); } @java.lang.Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.addRepeatedField(field, value); + return super.addRepeatedField(field, value); } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { @@ -6256,7 +6251,7 @@ public Builder mergeFrom( private java.util.List enrollments_ = java.util.Collections.emptyList(); private void ensureEnrollmentsIsMutable() { - if (!((bitField0_ & 0x00000001) == 0x00000001)) { + if (!((bitField0_ & 0x00000001) != 0)) { enrollments_ = new java.util.ArrayList(enrollments_); bitField0_ |= 0x00000001; } @@ -6485,7 +6480,7 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentInfo.Builder addEnrollmen enrollmentsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentInfo, ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentInfo.Builder, ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentInfoOrBuilder>( enrollments_, - ((bitField0_ & 0x00000001) == 0x00000001), + ((bitField0_ & 0x00000001) != 0), getParentForChildren(), isClean()); enrollments_ = null; @@ -6688,7 +6683,7 @@ private EnrollmentInfo( * required string type = 1; */ public boolean hasType() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** * required string type = 1; @@ -6730,7 +6725,7 @@ public java.lang.String getType() { * required string issuer = 2; */ public boolean hasIssuer() { - return ((bitField0_ & 0x00000002) == 0x00000002); + return ((bitField0_ & 0x00000002) != 0); } /** * required string issuer = 2; @@ -6772,7 +6767,7 @@ public java.lang.String getIssuer() { * required bytes public = 3; */ public boolean hasPublic() { - return ((bitField0_ & 0x00000004) == 0x00000004); + return ((bitField0_ & 0x00000004) != 0); } /** * required bytes public = 3; @@ -6807,13 +6802,13 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { com.google.protobuf.GeneratedMessageV3.writeString(output, 1, type_); } - if (((bitField0_ & 0x00000002) == 0x00000002)) { + if (((bitField0_ & 0x00000002) != 0)) { com.google.protobuf.GeneratedMessageV3.writeString(output, 2, issuer_); } - if (((bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) != 0)) { output.writeBytes(3, public_); } unknownFields.writeTo(output); @@ -6825,13 +6820,13 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { + if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, type_); } - if (((bitField0_ & 0x00000002) == 0x00000002)) { + if (((bitField0_ & 0x00000002) != 0)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, issuer_); } - if (((bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) != 0)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(3, public_); } @@ -6850,24 +6845,23 @@ public boolean equals(final java.lang.Object obj) { } ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentInfo other = (ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentInfo) obj; - boolean result = true; - result = result && (hasType() == other.hasType()); + if (hasType() != other.hasType()) return false; if (hasType()) { - result = result && getType() - .equals(other.getType()); + if (!getType() + .equals(other.getType())) return false; } - result = result && (hasIssuer() == other.hasIssuer()); + if (hasIssuer() != other.hasIssuer()) return false; if (hasIssuer()) { - result = result && getIssuer() - .equals(other.getIssuer()); + if (!getIssuer() + .equals(other.getIssuer())) return false; } - result = result && (hasPublic() == other.hasPublic()); + if (hasPublic() != other.hasPublic()) return false; if (hasPublic()) { - result = result && getPublic() - .equals(other.getPublic()); + if (!getPublic() + .equals(other.getPublic())) return false; } - result = result && unknownFields.equals(other.unknownFields); - return result; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; } @java.lang.Override @@ -7060,15 +7054,15 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentInfo buildPartial() { ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentInfo result = new ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentInfo(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + if (((from_bitField0_ & 0x00000001) != 0)) { to_bitField0_ |= 0x00000001; } result.type_ = type_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + if (((from_bitField0_ & 0x00000002) != 0)) { to_bitField0_ |= 0x00000002; } result.issuer_ = issuer_; - if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + if (((from_bitField0_ & 0x00000004) != 0)) { to_bitField0_ |= 0x00000004; } result.public_ = public_; @@ -7079,35 +7073,35 @@ public ch.epfl.dedis.lib.proto.AuthProxProto.EnrollmentInfo buildPartial() { @java.lang.Override public Builder clone() { - return (Builder) super.clone(); + return super.clone(); } @java.lang.Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.setField(field, value); + return super.setField(field, value); } @java.lang.Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { - return (Builder) super.clearField(field); + return super.clearField(field); } @java.lang.Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return (Builder) super.clearOneof(oneof); + return super.clearOneof(oneof); } @java.lang.Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { - return (Builder) super.setRepeatedField(field, index, value); + return super.setRepeatedField(field, index, value); } @java.lang.Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { - return (Builder) super.addRepeatedField(field, value); + return super.addRepeatedField(field, value); } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { @@ -7178,7 +7172,7 @@ public Builder mergeFrom( * required string type = 1; */ public boolean hasType() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** * required string type = 1; @@ -7254,7 +7248,7 @@ public Builder setTypeBytes( * required string issuer = 2; */ public boolean hasIssuer() { - return ((bitField0_ & 0x00000002) == 0x00000002); + return ((bitField0_ & 0x00000002) != 0); } /** * required string issuer = 2; @@ -7330,7 +7324,7 @@ public Builder setIssuerBytes( * required bytes public = 3; */ public boolean hasPublic() { - return ((bitField0_ & 0x00000004) == 0x00000004); + return ((bitField0_ & 0x00000004) != 0); } /** * required bytes public = 3; diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/ByzCoinProto.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/ByzCoinProto.java index c73c1af38b..058d238cd8 100644 --- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/ByzCoinProto.java +++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/ByzCoinProto.java @@ -110,7 +110,6 @@ private DataHeader() { trieroot_ = com.google.protobuf.ByteString.EMPTY; clienttransactionhash_ = com.google.protobuf.ByteString.EMPTY; statechangeshash_ = com.google.protobuf.ByteString.EMPTY; - timestamp_ = 0L; } @java.lang.Override @@ -201,7 +200,7 @@ private DataHeader( * required bytes trieroot = 1; */ public boolean hasTrieroot() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** *
@@ -225,7 +224,7 @@ public com.google.protobuf.ByteString getTrieroot() {
      * required bytes clienttransactionhash = 2;
      */
     public boolean hasClienttransactionhash() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -249,7 +248,7 @@ public com.google.protobuf.ByteString getClienttransactionhash() {
      * required bytes statechangeshash = 3;
      */
     public boolean hasStatechangeshash() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -273,7 +272,7 @@ public com.google.protobuf.ByteString getStatechangeshash() {
      * required sint64 timestamp = 4;
      */
     public boolean hasTimestamp() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * 
@@ -316,16 +315,16 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, trieroot_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, clienttransactionhash_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, statechangeshash_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeSInt64(4, timestamp_);
       }
       unknownFields.writeTo(output);
@@ -337,19 +336,19 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, trieroot_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, clienttransactionhash_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, statechangeshash_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt64Size(4, timestamp_);
       }
@@ -368,29 +367,28 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.DataHeader other = (ch.epfl.dedis.lib.proto.ByzCoinProto.DataHeader) obj;
 
-      boolean result = true;
-      result = result && (hasTrieroot() == other.hasTrieroot());
+      if (hasTrieroot() != other.hasTrieroot()) return false;
       if (hasTrieroot()) {
-        result = result && getTrieroot()
-            .equals(other.getTrieroot());
+        if (!getTrieroot()
+            .equals(other.getTrieroot())) return false;
       }
-      result = result && (hasClienttransactionhash() == other.hasClienttransactionhash());
+      if (hasClienttransactionhash() != other.hasClienttransactionhash()) return false;
       if (hasClienttransactionhash()) {
-        result = result && getClienttransactionhash()
-            .equals(other.getClienttransactionhash());
+        if (!getClienttransactionhash()
+            .equals(other.getClienttransactionhash())) return false;
       }
-      result = result && (hasStatechangeshash() == other.hasStatechangeshash());
+      if (hasStatechangeshash() != other.hasStatechangeshash()) return false;
       if (hasStatechangeshash()) {
-        result = result && getStatechangeshash()
-            .equals(other.getStatechangeshash());
+        if (!getStatechangeshash()
+            .equals(other.getStatechangeshash())) return false;
       }
-      result = result && (hasTimestamp() == other.hasTimestamp());
+      if (hasTimestamp() != other.hasTimestamp()) return false;
       if (hasTimestamp()) {
-        result = result && (getTimestamp()
-            == other.getTimestamp());
+        if (getTimestamp()
+            != other.getTimestamp()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -590,22 +588,22 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DataHeader buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.DataHeader result = new ch.epfl.dedis.lib.proto.ByzCoinProto.DataHeader(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.trieroot_ = trieroot_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.clienttransactionhash_ = clienttransactionhash_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.statechangeshash_ = statechangeshash_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          result.timestamp_ = timestamp_;
           to_bitField0_ |= 0x00000008;
         }
-        result.timestamp_ = timestamp_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -613,35 +611,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DataHeader buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -719,7 +717,7 @@ public Builder mergeFrom(
        * required bytes trieroot = 1;
        */
       public boolean hasTrieroot() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -773,7 +771,7 @@ public Builder clearTrieroot() {
        * required bytes clienttransactionhash = 2;
        */
       public boolean hasClienttransactionhash() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -825,7 +823,7 @@ public Builder clearClienttransactionhash() {
        * required bytes statechangeshash = 3;
        */
       public boolean hasStatechangeshash() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -879,7 +877,7 @@ public Builder clearStatechangeshash() {
        * required sint64 timestamp = 4;
        */
       public boolean hasTimestamp() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * 
@@ -1044,7 +1042,7 @@ private DataBody(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 txresults_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -1067,7 +1065,7 @@ private DataBody(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           txresults_ = java.util.Collections.unmodifiableList(txresults_);
         }
         this.unknownFields = unknownFields.build();
@@ -1173,11 +1171,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.DataBody other = (ch.epfl.dedis.lib.proto.ByzCoinProto.DataBody) obj;
 
-      boolean result = true;
-      result = result && getTxresultsList()
-          .equals(other.getTxresultsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getTxresultsList()
+          .equals(other.getTxresultsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -1364,7 +1361,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DataBody buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.DataBody result = new ch.epfl.dedis.lib.proto.ByzCoinProto.DataBody(this);
         int from_bitField0_ = bitField0_;
         if (txresultsBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             txresults_ = java.util.Collections.unmodifiableList(txresults_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -1378,35 +1375,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DataBody buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -1484,7 +1481,7 @@ public Builder mergeFrom(
       private java.util.List txresults_ =
         java.util.Collections.emptyList();
       private void ensureTxresultsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           txresults_ = new java.util.ArrayList(txresults_);
           bitField0_ |= 0x00000001;
          }
@@ -1713,7 +1710,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.TxResult.Builder addTxresultsBuilder
           txresultsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.ByzCoinProto.TxResult, ch.epfl.dedis.lib.proto.ByzCoinProto.TxResult.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.TxResultOrBuilder>(
                   txresults_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           txresults_ = null;
@@ -1934,9 +1931,6 @@ private CreateGenesisBlock(com.google.protobuf.GeneratedMessageV3.Builder bui
       super(builder);
     }
     private CreateGenesisBlock() {
-      version_ = 0;
-      blockinterval_ = 0L;
-      maxblocksize_ = 0;
       darccontractids_ = com.google.protobuf.LazyStringArrayList.EMPTY;
     }
 
@@ -1971,7 +1965,7 @@ private CreateGenesisBlock(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = roster_.toBuilder();
               }
               roster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry);
@@ -1984,7 +1978,7 @@ private CreateGenesisBlock(
             }
             case 26: {
               ch.epfl.dedis.lib.proto.DarcProto.Darc.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (((bitField0_ & 0x00000004) != 0)) {
                 subBuilder = genesisdarc_.toBuilder();
               }
               genesisdarc_ = input.readMessage(ch.epfl.dedis.lib.proto.DarcProto.Darc.parser(), extensionRegistry);
@@ -2007,7 +2001,7 @@ private CreateGenesisBlock(
             }
             case 50: {
               com.google.protobuf.ByteString bs = input.readBytes();
-              if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+              if (!((mutable_bitField0_ & 0x00000020) != 0)) {
                 darccontractids_ = new com.google.protobuf.LazyStringArrayList();
                 mutable_bitField0_ |= 0x00000020;
               }
@@ -2029,7 +2023,7 @@ private CreateGenesisBlock(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+        if (((mutable_bitField0_ & 0x00000020) != 0)) {
           darccontractids_ = darccontractids_.getUnmodifiableView();
         }
         this.unknownFields = unknownFields.build();
@@ -2060,7 +2054,7 @@ private CreateGenesisBlock(
      * required sint32 version = 1;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -2083,7 +2077,7 @@ public int getVersion() {
      * required .onet.Roster roster = 2;
      */
     public boolean hasRoster() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -2116,7 +2110,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() {
      * required .darc.Darc genesisdarc = 3;
      */
     public boolean hasGenesisdarc() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -2149,7 +2143,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.DarcOrBuilder getGenesisdarcOrBuilder()
      * required sint64 blockinterval = 4;
      */
     public boolean hasBlockinterval() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * 
@@ -2172,7 +2166,7 @@ public long getBlockinterval() {
      * optional sint32 maxblocksize = 5;
      */
     public boolean hasMaxblocksize() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * 
@@ -2272,19 +2266,19 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getRoster());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeMessage(3, getGenesisdarc());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeSInt64(4, blockinterval_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         output.writeSInt32(5, maxblocksize_);
       }
       for (int i = 0; i < darccontractids_.size(); i++) {
@@ -2299,23 +2293,23 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getRoster());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getGenesisdarc());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt64Size(4, blockinterval_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(5, maxblocksize_);
       }
@@ -2342,36 +2336,35 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlock other = (ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlock) obj;
 
-      boolean result = true;
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && (hasRoster() == other.hasRoster());
+      if (hasRoster() != other.hasRoster()) return false;
       if (hasRoster()) {
-        result = result && getRoster()
-            .equals(other.getRoster());
+        if (!getRoster()
+            .equals(other.getRoster())) return false;
       }
-      result = result && (hasGenesisdarc() == other.hasGenesisdarc());
+      if (hasGenesisdarc() != other.hasGenesisdarc()) return false;
       if (hasGenesisdarc()) {
-        result = result && getGenesisdarc()
-            .equals(other.getGenesisdarc());
+        if (!getGenesisdarc()
+            .equals(other.getGenesisdarc())) return false;
       }
-      result = result && (hasBlockinterval() == other.hasBlockinterval());
+      if (hasBlockinterval() != other.hasBlockinterval()) return false;
       if (hasBlockinterval()) {
-        result = result && (getBlockinterval()
-            == other.getBlockinterval());
+        if (getBlockinterval()
+            != other.getBlockinterval()) return false;
       }
-      result = result && (hasMaxblocksize() == other.hasMaxblocksize());
+      if (hasMaxblocksize() != other.hasMaxblocksize()) return false;
       if (hasMaxblocksize()) {
-        result = result && (getMaxblocksize()
-            == other.getMaxblocksize());
+        if (getMaxblocksize()
+            != other.getMaxblocksize()) return false;
       }
-      result = result && getDarccontractidsList()
-          .equals(other.getDarccontractidsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getDarccontractidsList()
+          .equals(other.getDarccontractidsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -2593,35 +2586,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlock buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlock result = new ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlock(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000001;
         }
-        result.version_ = version_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (rosterBuilder_ == null) {
+            result.roster_ = roster_;
+          } else {
+            result.roster_ = rosterBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (rosterBuilder_ == null) {
-          result.roster_ = roster_;
-        } else {
-          result.roster_ = rosterBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          if (genesisdarcBuilder_ == null) {
+            result.genesisdarc_ = genesisdarc_;
+          } else {
+            result.genesisdarc_ = genesisdarcBuilder_.build();
+          }
           to_bitField0_ |= 0x00000004;
         }
-        if (genesisdarcBuilder_ == null) {
-          result.genesisdarc_ = genesisdarc_;
-        } else {
-          result.genesisdarc_ = genesisdarcBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          result.blockinterval_ = blockinterval_;
           to_bitField0_ |= 0x00000008;
         }
-        result.blockinterval_ = blockinterval_;
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((from_bitField0_ & 0x00000010) != 0)) {
+          result.maxblocksize_ = maxblocksize_;
           to_bitField0_ |= 0x00000010;
         }
-        result.maxblocksize_ = maxblocksize_;
-        if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        if (((bitField0_ & 0x00000020) != 0)) {
           darccontractids_ = darccontractids_.getUnmodifiableView();
           bitField0_ = (bitField0_ & ~0x00000020);
         }
@@ -2633,35 +2626,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlock buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -2757,7 +2750,7 @@ public Builder mergeFrom(
        * required sint32 version = 1;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -2796,7 +2789,7 @@ public Builder clearVersion() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_ = null;
+      private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> rosterBuilder_;
       /**
@@ -2807,7 +2800,7 @@ public Builder clearVersion() {
        * required .onet.Roster roster = 2;
        */
       public boolean hasRoster() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -2870,7 +2863,7 @@ public Builder setRoster(
        */
       public Builder mergeRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) {
         if (rosterBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               roster_ != null &&
               roster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) {
             roster_ =
@@ -2950,7 +2943,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() {
         return rosterBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.DarcProto.Darc genesisdarc_ = null;
+      private ch.epfl.dedis.lib.proto.DarcProto.Darc genesisdarc_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.DarcProto.Darc, ch.epfl.dedis.lib.proto.DarcProto.Darc.Builder, ch.epfl.dedis.lib.proto.DarcProto.DarcOrBuilder> genesisdarcBuilder_;
       /**
@@ -2961,7 +2954,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() {
        * required .darc.Darc genesisdarc = 3;
        */
       public boolean hasGenesisdarc() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -3024,7 +3017,7 @@ public Builder setGenesisdarc(
        */
       public Builder mergeGenesisdarc(ch.epfl.dedis.lib.proto.DarcProto.Darc value) {
         if (genesisdarcBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+          if (((bitField0_ & 0x00000004) != 0) &&
               genesisdarc_ != null &&
               genesisdarc_ != ch.epfl.dedis.lib.proto.DarcProto.Darc.getDefaultInstance()) {
             genesisdarc_ =
@@ -3113,7 +3106,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.DarcOrBuilder getGenesisdarcOrBuilder()
        * required sint64 blockinterval = 4;
        */
       public boolean hasBlockinterval() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * 
@@ -3161,7 +3154,7 @@ public Builder clearBlockinterval() {
        * optional sint32 maxblocksize = 5;
        */
       public boolean hasMaxblocksize() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return ((bitField0_ & 0x00000010) != 0);
       }
       /**
        * 
@@ -3202,7 +3195,7 @@ public Builder clearMaxblocksize() {
 
       private com.google.protobuf.LazyStringList darccontractids_ = com.google.protobuf.LazyStringArrayList.EMPTY;
       private void ensureDarccontractidsIsMutable() {
-        if (!((bitField0_ & 0x00000020) == 0x00000020)) {
+        if (!((bitField0_ & 0x00000020) != 0)) {
           darccontractids_ = new com.google.protobuf.LazyStringArrayList(darccontractids_);
           bitField0_ |= 0x00000020;
          }
@@ -3453,7 +3446,6 @@ private CreateGenesisBlockResponse(com.google.protobuf.GeneratedMessageV3.Builde
       super(builder);
     }
     private CreateGenesisBlockResponse() {
-      version_ = 0;
     }
 
     @java.lang.Override
@@ -3487,7 +3479,7 @@ private CreateGenesisBlockResponse(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = skipblock_.toBuilder();
               }
               skipblock_ = input.readMessage(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.parser(), extensionRegistry);
@@ -3541,7 +3533,7 @@ private CreateGenesisBlockResponse(
      * required sint32 version = 1;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -3564,7 +3556,7 @@ public int getVersion() {
      * optional .skipchain.SkipBlock skipblock = 2;
      */
     public boolean hasSkipblock() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -3611,10 +3603,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getSkipblock());
       }
       unknownFields.writeTo(output);
@@ -3626,11 +3618,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getSkipblock());
       }
@@ -3649,19 +3641,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlockResponse other = (ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlockResponse) obj;
 
-      boolean result = true;
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && (hasSkipblock() == other.hasSkipblock());
+      if (hasSkipblock() != other.hasSkipblock()) return false;
       if (hasSkipblock()) {
-        result = result && getSkipblock()
-            .equals(other.getSkipblock());
+        if (!getSkipblock()
+            .equals(other.getSkipblock())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -3853,18 +3844,18 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlockResponse buildPart
         ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlockResponse result = new ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlockResponse(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000001;
         }
-        result.version_ = version_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (skipblockBuilder_ == null) {
+            result.skipblock_ = skipblock_;
+          } else {
+            result.skipblock_ = skipblockBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (skipblockBuilder_ == null) {
-          result.skipblock_ = skipblock_;
-        } else {
-          result.skipblock_ = skipblockBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -3872,35 +3863,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CreateGenesisBlockResponse buildPart
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -3967,7 +3958,7 @@ public Builder mergeFrom(
        * required sint32 version = 1;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -4006,7 +3997,7 @@ public Builder clearVersion() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock skipblock_ = null;
+      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock skipblock_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder> skipblockBuilder_;
       /**
@@ -4017,7 +4008,7 @@ public Builder clearVersion() {
        * optional .skipchain.SkipBlock skipblock = 2;
        */
       public boolean hasSkipblock() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -4080,7 +4071,7 @@ public Builder setSkipblock(
        */
       public Builder mergeSkipblock(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock value) {
         if (skipblockBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               skipblock_ != null &&
               skipblock_ != ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.getDefaultInstance()) {
             skipblock_ =
@@ -4311,9 +4302,7 @@ private AddTxRequest(com.google.protobuf.GeneratedMessageV3.Builder builder)
       super(builder);
     }
     private AddTxRequest() {
-      version_ = 0;
       skipchainid_ = com.google.protobuf.ByteString.EMPTY;
-      inclusionwait_ = 0;
     }
 
     @java.lang.Override
@@ -4352,7 +4341,7 @@ private AddTxRequest(
             }
             case 26: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (((bitField0_ & 0x00000004) != 0)) {
                 subBuilder = transaction_.toBuilder();
               }
               transaction_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction.parser(), extensionRegistry);
@@ -4411,7 +4400,7 @@ private AddTxRequest(
      * required sint32 version = 1;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -4434,7 +4423,7 @@ public int getVersion() {
      * required bytes skipchainid = 2;
      */
     public boolean hasSkipchainid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -4457,7 +4446,7 @@ public com.google.protobuf.ByteString getSkipchainid() {
      * required .byzcoin.ClientTransaction transaction = 3;
      */
     public boolean hasTransaction() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -4491,7 +4480,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransactionOrBuilder getTransa
      * optional sint32 inclusionwait = 4;
      */
     public boolean hasInclusionwait() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * 
@@ -4535,16 +4524,16 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, skipchainid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeMessage(3, getTransaction());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeSInt32(4, inclusionwait_);
       }
       unknownFields.writeTo(output);
@@ -4556,19 +4545,19 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, skipchainid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getTransaction());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(4, inclusionwait_);
       }
@@ -4587,29 +4576,28 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxRequest other = (ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxRequest) obj;
 
-      boolean result = true;
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && (hasSkipchainid() == other.hasSkipchainid());
+      if (hasSkipchainid() != other.hasSkipchainid()) return false;
       if (hasSkipchainid()) {
-        result = result && getSkipchainid()
-            .equals(other.getSkipchainid());
+        if (!getSkipchainid()
+            .equals(other.getSkipchainid())) return false;
       }
-      result = result && (hasTransaction() == other.hasTransaction());
+      if (hasTransaction() != other.hasTransaction()) return false;
       if (hasTransaction()) {
-        result = result && getTransaction()
-            .equals(other.getTransaction());
+        if (!getTransaction()
+            .equals(other.getTransaction())) return false;
       }
-      result = result && (hasInclusionwait() == other.hasInclusionwait());
+      if (hasInclusionwait() != other.hasInclusionwait()) return false;
       if (hasInclusionwait()) {
-        result = result && (getInclusionwait()
-            == other.getInclusionwait());
+        if (getInclusionwait()
+            != other.getInclusionwait()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -4813,26 +4801,26 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxRequest buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxRequest result = new ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxRequest(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000001;
         }
-        result.version_ = version_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.skipchainid_ = skipchainid_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          if (transactionBuilder_ == null) {
+            result.transaction_ = transaction_;
+          } else {
+            result.transaction_ = transactionBuilder_.build();
+          }
           to_bitField0_ |= 0x00000004;
         }
-        if (transactionBuilder_ == null) {
-          result.transaction_ = transaction_;
-        } else {
-          result.transaction_ = transactionBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          result.inclusionwait_ = inclusionwait_;
           to_bitField0_ |= 0x00000008;
         }
-        result.inclusionwait_ = inclusionwait_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -4840,35 +4828,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxRequest buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -4945,7 +4933,7 @@ public Builder mergeFrom(
        * required sint32 version = 1;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -4993,7 +4981,7 @@ public Builder clearVersion() {
        * required bytes skipchainid = 2;
        */
       public boolean hasSkipchainid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -5035,7 +5023,7 @@ public Builder clearSkipchainid() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction transaction_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction transaction_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction, ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransactionOrBuilder> transactionBuilder_;
       /**
@@ -5046,7 +5034,7 @@ public Builder clearSkipchainid() {
        * required .byzcoin.ClientTransaction transaction = 3;
        */
       public boolean hasTransaction() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -5109,7 +5097,7 @@ public Builder setTransaction(
        */
       public Builder mergeTransaction(ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction value) {
         if (transactionBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+          if (((bitField0_ & 0x00000004) != 0) &&
               transaction_ != null &&
               transaction_ != ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction.getDefaultInstance()) {
             transaction_ =
@@ -5199,7 +5187,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransactionOrBuilder getTransa
        * optional sint32 inclusionwait = 4;
        */
       public boolean hasInclusionwait() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * 
@@ -5331,7 +5319,6 @@ private AddTxResponse(com.google.protobuf.GeneratedMessageV3.Builder builder)
       super(builder);
     }
     private AddTxResponse() {
-      version_ = 0;
     }
 
     @java.lang.Override
@@ -5406,7 +5393,7 @@ private AddTxResponse(
      * required sint32 version = 1;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -5437,7 +5424,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, version_);
       }
       unknownFields.writeTo(output);
@@ -5449,7 +5436,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, version_);
       }
@@ -5468,14 +5455,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxResponse other = (ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxResponse) obj;
 
-      boolean result = true;
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -5656,10 +5642,10 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxResponse buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxResponse result = new ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxResponse(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000001;
         }
-        result.version_ = version_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -5667,35 +5653,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.AddTxResponse buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -5754,7 +5740,7 @@ public Builder mergeFrom(
        * required sint32 version = 1;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -5919,7 +5905,6 @@ private GetProof(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private GetProof() {
-      version_ = 0;
       key_ = com.google.protobuf.ByteString.EMPTY;
       id_ = com.google.protobuf.ByteString.EMPTY;
     }
@@ -6006,7 +5991,7 @@ private GetProof(
      * required sint32 version = 1;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -6029,7 +6014,7 @@ public int getVersion() {
      * required bytes key = 2;
      */
     public boolean hasKey() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -6053,7 +6038,7 @@ public com.google.protobuf.ByteString getKey() {
      * required bytes id = 3;
      */
     public boolean hasId() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -6093,13 +6078,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, key_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, id_);
       }
       unknownFields.writeTo(output);
@@ -6111,15 +6096,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, key_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, id_);
       }
@@ -6138,24 +6123,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.GetProof other = (ch.epfl.dedis.lib.proto.ByzCoinProto.GetProof) obj;
 
-      boolean result = true;
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && (hasKey() == other.hasKey());
+      if (hasKey() != other.hasKey()) return false;
       if (hasKey()) {
-        result = result && getKey()
-            .equals(other.getKey());
+        if (!getKey()
+            .equals(other.getKey())) return false;
       }
-      result = result && (hasId() == other.hasId());
+      if (hasId() != other.hasId()) return false;
       if (hasId()) {
-        result = result && getId()
-            .equals(other.getId());
+        if (!getId()
+            .equals(other.getId())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -6348,15 +6332,15 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetProof buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.GetProof result = new ch.epfl.dedis.lib.proto.ByzCoinProto.GetProof(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000001;
         }
-        result.version_ = version_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.key_ = key_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.id_ = id_;
@@ -6367,35 +6351,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetProof buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -6466,7 +6450,7 @@ public Builder mergeFrom(
        * required sint32 version = 1;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -6514,7 +6498,7 @@ public Builder clearVersion() {
        * required bytes key = 2;
        */
       public boolean hasKey() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -6566,7 +6550,7 @@ public Builder clearKey() {
        * required bytes id = 3;
        */
       public boolean hasId() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -6730,7 +6714,6 @@ private GetProofResponse(com.google.protobuf.GeneratedMessageV3.Builder build
       super(builder);
     }
     private GetProofResponse() {
-      version_ = 0;
     }
 
     @java.lang.Override
@@ -6764,7 +6747,7 @@ private GetProofResponse(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = proof_.toBuilder();
               }
               proof_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.parser(), extensionRegistry);
@@ -6818,7 +6801,7 @@ private GetProofResponse(
      * required sint32 version = 1;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -6842,7 +6825,7 @@ public int getVersion() {
      * required .byzcoin.Proof proof = 2;
      */
     public boolean hasProof() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -6893,10 +6876,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getProof());
       }
       unknownFields.writeTo(output);
@@ -6908,11 +6891,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getProof());
       }
@@ -6931,19 +6914,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.GetProofResponse other = (ch.epfl.dedis.lib.proto.ByzCoinProto.GetProofResponse) obj;
 
-      boolean result = true;
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && (hasProof() == other.hasProof());
+      if (hasProof() != other.hasProof()) return false;
       if (hasProof()) {
-        result = result && getProof()
-            .equals(other.getProof());
+        if (!getProof()
+            .equals(other.getProof())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -7136,18 +7118,18 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetProofResponse buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.GetProofResponse result = new ch.epfl.dedis.lib.proto.ByzCoinProto.GetProofResponse(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000001;
         }
-        result.version_ = version_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (proofBuilder_ == null) {
+            result.proof_ = proof_;
+          } else {
+            result.proof_ = proofBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (proofBuilder_ == null) {
-          result.proof_ = proof_;
-        } else {
-          result.proof_ = proofBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -7155,35 +7137,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetProofResponse buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -7251,7 +7233,7 @@ public Builder mergeFrom(
        * required sint32 version = 1;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -7290,7 +7272,7 @@ public Builder clearVersion() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof proof_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof proof_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> proofBuilder_;
       /**
@@ -7302,7 +7284,7 @@ public Builder clearVersion() {
        * required .byzcoin.Proof proof = 2;
        */
       public boolean hasProof() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -7369,7 +7351,7 @@ public Builder setProof(
        */
       public Builder mergeProof(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) {
         if (proofBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               proof_ != null &&
               proof_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance()) {
             proof_ =
@@ -7622,7 +7604,6 @@ private CheckAuthorization(com.google.protobuf.GeneratedMessageV3.Builder bui
       super(builder);
     }
     private CheckAuthorization() {
-      version_ = 0;
       byzcoinid_ = com.google.protobuf.ByteString.EMPTY;
       darcid_ = com.google.protobuf.ByteString.EMPTY;
       identities_ = java.util.Collections.emptyList();
@@ -7668,7 +7649,7 @@ private CheckAuthorization(
               break;
             }
             case 34: {
-              if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+              if (!((mutable_bitField0_ & 0x00000008) != 0)) {
                 identities_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000008;
               }
@@ -7691,7 +7672,7 @@ private CheckAuthorization(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((mutable_bitField0_ & 0x00000008) != 0)) {
           identities_ = java.util.Collections.unmodifiableList(identities_);
         }
         this.unknownFields = unknownFields.build();
@@ -7722,7 +7703,7 @@ private CheckAuthorization(
      * required sint32 version = 1;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -7745,7 +7726,7 @@ public int getVersion() {
      * required bytes byzcoinid = 2;
      */
     public boolean hasByzcoinid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -7768,7 +7749,7 @@ public com.google.protobuf.ByteString getByzcoinid() {
      * required bytes darcid = 3;
      */
     public boolean hasDarcid() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -7868,13 +7849,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, darcid_);
       }
       for (int i = 0; i < identities_.size(); i++) {
@@ -7889,15 +7870,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, darcid_);
       }
@@ -7920,26 +7901,25 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorization other = (ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorization) obj;
 
-      boolean result = true;
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && (hasByzcoinid() == other.hasByzcoinid());
+      if (hasByzcoinid() != other.hasByzcoinid()) return false;
       if (hasByzcoinid()) {
-        result = result && getByzcoinid()
-            .equals(other.getByzcoinid());
+        if (!getByzcoinid()
+            .equals(other.getByzcoinid())) return false;
       }
-      result = result && (hasDarcid() == other.hasDarcid());
+      if (hasDarcid() != other.hasDarcid()) return false;
       if (hasDarcid()) {
-        result = result && getDarcid()
-            .equals(other.getDarcid());
+        if (!getDarcid()
+            .equals(other.getDarcid())) return false;
       }
-      result = result && getIdentitiesList()
-          .equals(other.getIdentitiesList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getIdentitiesList()
+          .equals(other.getIdentitiesList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -8144,20 +8124,20 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorization buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorization result = new ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorization(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000001;
         }
-        result.version_ = version_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.byzcoinid_ = byzcoinid_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.darcid_ = darcid_;
         if (identitiesBuilder_ == null) {
-          if (((bitField0_ & 0x00000008) == 0x00000008)) {
+          if (((bitField0_ & 0x00000008) != 0)) {
             identities_ = java.util.Collections.unmodifiableList(identities_);
             bitField0_ = (bitField0_ & ~0x00000008);
           }
@@ -8172,35 +8152,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorization buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -8302,7 +8282,7 @@ public Builder mergeFrom(
        * required sint32 version = 1;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -8350,7 +8330,7 @@ public Builder clearVersion() {
        * required bytes byzcoinid = 2;
        */
       public boolean hasByzcoinid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -8401,7 +8381,7 @@ public Builder clearByzcoinid() {
        * required bytes darcid = 3;
        */
       public boolean hasDarcid() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -8446,7 +8426,7 @@ public Builder clearDarcid() {
       private java.util.List identities_ =
         java.util.Collections.emptyList();
       private void ensureIdentitiesIsMutable() {
-        if (!((bitField0_ & 0x00000008) == 0x00000008)) {
+        if (!((bitField0_ & 0x00000008) != 0)) {
           identities_ = new java.util.ArrayList(identities_);
           bitField0_ |= 0x00000008;
          }
@@ -8747,7 +8727,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Identity.Builder addIdentitiesBuilder(
           identitiesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.DarcProto.Identity, ch.epfl.dedis.lib.proto.DarcProto.Identity.Builder, ch.epfl.dedis.lib.proto.DarcProto.IdentityOrBuilder>(
                   identities_,
-                  ((bitField0_ & 0x00000008) == 0x00000008),
+                  ((bitField0_ & 0x00000008) != 0),
                   getParentForChildren(),
                   isClean());
           identities_ = null;
@@ -8878,7 +8858,7 @@ private CheckAuthorizationResponse(
               break;
             case 10: {
               com.google.protobuf.ByteString bs = input.readBytes();
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 actions_ = new com.google.protobuf.LazyStringArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -8900,7 +8880,7 @@ private CheckAuthorizationResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           actions_ = actions_.getUnmodifiableView();
         }
         this.unknownFields = unknownFields.build();
@@ -8998,11 +8978,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorizationResponse other = (ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorizationResponse) obj;
 
-      boolean result = true;
-      result = result && getActionsList()
-          .equals(other.getActionsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getActionsList()
+          .equals(other.getActionsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -9184,7 +9163,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorizationResponse build() {
       public ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorizationResponse buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorizationResponse result = new ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorizationResponse(this);
         int from_bitField0_ = bitField0_;
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((bitField0_ & 0x00000001) != 0)) {
           actions_ = actions_.getUnmodifiableView();
           bitField0_ = (bitField0_ & ~0x00000001);
         }
@@ -9195,35 +9174,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CheckAuthorizationResponse buildPart
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -9279,7 +9258,7 @@ public Builder mergeFrom(
 
       private com.google.protobuf.LazyStringList actions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
       private void ensureActionsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           actions_ = new com.google.protobuf.LazyStringArrayList(actions_);
           bitField0_ |= 0x00000001;
          }
@@ -9494,8 +9473,6 @@ private ChainConfig(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private ChainConfig() {
-      blockinterval_ = 0L;
-      maxblocksize_ = 0;
       darccontractids_ = com.google.protobuf.LazyStringArrayList.EMPTY;
     }
 
@@ -9530,7 +9507,7 @@ private ChainConfig(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = roster_.toBuilder();
               }
               roster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry);
@@ -9548,7 +9525,7 @@ private ChainConfig(
             }
             case 34: {
               com.google.protobuf.ByteString bs = input.readBytes();
-              if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+              if (!((mutable_bitField0_ & 0x00000008) != 0)) {
                 darccontractids_ = new com.google.protobuf.LazyStringArrayList();
                 mutable_bitField0_ |= 0x00000008;
               }
@@ -9570,7 +9547,7 @@ private ChainConfig(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((mutable_bitField0_ & 0x00000008) != 0)) {
           darccontractids_ = darccontractids_.getUnmodifiableView();
         }
         this.unknownFields = unknownFields.build();
@@ -9597,7 +9574,7 @@ private ChainConfig(
      * required sint64 blockinterval = 1;
      */
     public boolean hasBlockinterval() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required sint64 blockinterval = 1;
@@ -9612,7 +9589,7 @@ public long getBlockinterval() {
      * required .onet.Roster roster = 2;
      */
     public boolean hasRoster() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required .onet.Roster roster = 2;
@@ -9633,7 +9610,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() {
      * required sint32 maxblocksize = 3;
      */
     public boolean hasMaxblocksize() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required sint32 maxblocksize = 3;
@@ -9701,13 +9678,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt64(1, blockinterval_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getRoster());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeSInt32(3, maxblocksize_);
       }
       for (int i = 0; i < darccontractids_.size(); i++) {
@@ -9722,15 +9699,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt64Size(1, blockinterval_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getRoster());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(3, maxblocksize_);
       }
@@ -9757,26 +9734,25 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.ChainConfig other = (ch.epfl.dedis.lib.proto.ByzCoinProto.ChainConfig) obj;
 
-      boolean result = true;
-      result = result && (hasBlockinterval() == other.hasBlockinterval());
+      if (hasBlockinterval() != other.hasBlockinterval()) return false;
       if (hasBlockinterval()) {
-        result = result && (getBlockinterval()
-            == other.getBlockinterval());
+        if (getBlockinterval()
+            != other.getBlockinterval()) return false;
       }
-      result = result && (hasRoster() == other.hasRoster());
+      if (hasRoster() != other.hasRoster()) return false;
       if (hasRoster()) {
-        result = result && getRoster()
-            .equals(other.getRoster());
+        if (!getRoster()
+            .equals(other.getRoster())) return false;
       }
-      result = result && (hasMaxblocksize() == other.hasMaxblocksize());
+      if (hasMaxblocksize() != other.hasMaxblocksize()) return false;
       if (hasMaxblocksize()) {
-        result = result && (getMaxblocksize()
-            == other.getMaxblocksize());
+        if (getMaxblocksize()
+            != other.getMaxblocksize()) return false;
       }
-      result = result && getDarccontractidsList()
-          .equals(other.getDarccontractidsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getDarccontractidsList()
+          .equals(other.getDarccontractidsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -9982,23 +9958,23 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.ChainConfig buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.ChainConfig result = new ch.epfl.dedis.lib.proto.ByzCoinProto.ChainConfig(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.blockinterval_ = blockinterval_;
           to_bitField0_ |= 0x00000001;
         }
-        result.blockinterval_ = blockinterval_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (rosterBuilder_ == null) {
+            result.roster_ = roster_;
+          } else {
+            result.roster_ = rosterBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (rosterBuilder_ == null) {
-          result.roster_ = roster_;
-        } else {
-          result.roster_ = rosterBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          result.maxblocksize_ = maxblocksize_;
           to_bitField0_ |= 0x00000004;
         }
-        result.maxblocksize_ = maxblocksize_;
-        if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((bitField0_ & 0x00000008) != 0)) {
           darccontractids_ = darccontractids_.getUnmodifiableView();
           bitField0_ = (bitField0_ & ~0x00000008);
         }
@@ -10010,35 +9986,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.ChainConfig buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -10118,7 +10094,7 @@ public Builder mergeFrom(
        * required sint64 blockinterval = 1;
        */
       public boolean hasBlockinterval() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required sint64 blockinterval = 1;
@@ -10145,14 +10121,14 @@ public Builder clearBlockinterval() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_ = null;
+      private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> rosterBuilder_;
       /**
        * required .onet.Roster roster = 2;
        */
       public boolean hasRoster() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required .onet.Roster roster = 2;
@@ -10199,7 +10175,7 @@ public Builder setRoster(
        */
       public Builder mergeRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) {
         if (rosterBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               roster_ != null &&
               roster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) {
             roster_ =
@@ -10268,7 +10244,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() {
        * required sint32 maxblocksize = 3;
        */
       public boolean hasMaxblocksize() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required sint32 maxblocksize = 3;
@@ -10297,7 +10273,7 @@ public Builder clearMaxblocksize() {
 
       private com.google.protobuf.LazyStringList darccontractids_ = com.google.protobuf.LazyStringArrayList.EMPTY;
       private void ensureDarccontractidsIsMutable() {
-        if (!((bitField0_ & 0x00000008) == 0x00000008)) {
+        if (!((bitField0_ & 0x00000008) != 0)) {
           darccontractids_ = new com.google.protobuf.LazyStringArrayList(darccontractids_);
           bitField0_ |= 0x00000008;
          }
@@ -10601,7 +10577,7 @@ private Proof(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.TrieProto.Proof.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = inclusionproof_.toBuilder();
               }
               inclusionproof_ = input.readMessage(ch.epfl.dedis.lib.proto.TrieProto.Proof.parser(), extensionRegistry);
@@ -10614,7 +10590,7 @@ private Proof(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = latest_.toBuilder();
               }
               latest_ = input.readMessage(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.parser(), extensionRegistry);
@@ -10626,7 +10602,7 @@ private Proof(
               break;
             }
             case 26: {
-              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+              if (!((mutable_bitField0_ & 0x00000004) != 0)) {
                 links_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000004;
               }
@@ -10649,7 +10625,7 @@ private Proof(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((mutable_bitField0_ & 0x00000004) != 0)) {
           links_ = java.util.Collections.unmodifiableList(links_);
         }
         this.unknownFields = unknownFields.build();
@@ -10680,7 +10656,7 @@ private Proof(
      * required .trie.Proof inclusionproof = 1;
      */
     public boolean hasInclusionproof() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -10713,7 +10689,7 @@ public ch.epfl.dedis.lib.proto.TrieProto.ProofOrBuilder getInclusionproofOrBuild
      * required .skipchain.SkipBlock latest = 2;
      */
     public boolean hasLatest() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -10837,10 +10813,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getInclusionproof());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getLatest());
       }
       for (int i = 0; i < links_.size(); i++) {
@@ -10855,11 +10831,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getInclusionproof());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getLatest());
       }
@@ -10882,21 +10858,20 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.Proof other = (ch.epfl.dedis.lib.proto.ByzCoinProto.Proof) obj;
 
-      boolean result = true;
-      result = result && (hasInclusionproof() == other.hasInclusionproof());
+      if (hasInclusionproof() != other.hasInclusionproof()) return false;
       if (hasInclusionproof()) {
-        result = result && getInclusionproof()
-            .equals(other.getInclusionproof());
+        if (!getInclusionproof()
+            .equals(other.getInclusionproof())) return false;
       }
-      result = result && (hasLatest() == other.hasLatest());
+      if (hasLatest() != other.hasLatest()) return false;
       if (hasLatest()) {
-        result = result && getLatest()
-            .equals(other.getLatest());
+        if (!getLatest()
+            .equals(other.getLatest())) return false;
       }
-      result = result && getLinksList()
-          .equals(other.getLinksList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getLinksList()
+          .equals(other.getLinksList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -11111,24 +11086,24 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.Proof result = new ch.epfl.dedis.lib.proto.ByzCoinProto.Proof(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (inclusionproofBuilder_ == null) {
+            result.inclusionproof_ = inclusionproof_;
+          } else {
+            result.inclusionproof_ = inclusionproofBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (inclusionproofBuilder_ == null) {
-          result.inclusionproof_ = inclusionproof_;
-        } else {
-          result.inclusionproof_ = inclusionproofBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (latestBuilder_ == null) {
+            result.latest_ = latest_;
+          } else {
+            result.latest_ = latestBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (latestBuilder_ == null) {
-          result.latest_ = latest_;
-        } else {
-          result.latest_ = latestBuilder_.build();
-        }
         if (linksBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004)) {
+          if (((bitField0_ & 0x00000004) != 0)) {
             links_ = java.util.Collections.unmodifiableList(links_);
             bitField0_ = (bitField0_ & ~0x00000004);
           }
@@ -11143,35 +11118,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -11264,7 +11239,7 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.TrieProto.Proof inclusionproof_ = null;
+      private ch.epfl.dedis.lib.proto.TrieProto.Proof inclusionproof_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.TrieProto.Proof, ch.epfl.dedis.lib.proto.TrieProto.Proof.Builder, ch.epfl.dedis.lib.proto.TrieProto.ProofOrBuilder> inclusionproofBuilder_;
       /**
@@ -11275,7 +11250,7 @@ public Builder mergeFrom(
        * required .trie.Proof inclusionproof = 1;
        */
       public boolean hasInclusionproof() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -11338,7 +11313,7 @@ public Builder setInclusionproof(
        */
       public Builder mergeInclusionproof(ch.epfl.dedis.lib.proto.TrieProto.Proof value) {
         if (inclusionproofBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               inclusionproof_ != null &&
               inclusionproof_ != ch.epfl.dedis.lib.proto.TrieProto.Proof.getDefaultInstance()) {
             inclusionproof_ =
@@ -11418,7 +11393,7 @@ public ch.epfl.dedis.lib.proto.TrieProto.ProofOrBuilder getInclusionproofOrBuild
         return inclusionproofBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock latest_ = null;
+      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock latest_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder> latestBuilder_;
       /**
@@ -11429,7 +11404,7 @@ public ch.epfl.dedis.lib.proto.TrieProto.ProofOrBuilder getInclusionproofOrBuild
        * required .skipchain.SkipBlock latest = 2;
        */
       public boolean hasLatest() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -11492,7 +11467,7 @@ public Builder setLatest(
        */
       public Builder mergeLatest(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock value) {
         if (latestBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               latest_ != null &&
               latest_ != ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.getDefaultInstance()) {
             latest_ =
@@ -11575,7 +11550,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder getLatestOrBuil
       private java.util.List links_ =
         java.util.Collections.emptyList();
       private void ensureLinksIsMutable() {
-        if (!((bitField0_ & 0x00000004) == 0x00000004)) {
+        if (!((bitField0_ & 0x00000004) != 0)) {
           links_ = new java.util.ArrayList(links_);
           bitField0_ |= 0x00000004;
          }
@@ -11912,7 +11887,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink.Builder addLinksBuilde
           linksBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink, ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLinkOrBuilder>(
                   links_,
-                  ((bitField0_ & 0x00000004) == 0x00000004),
+                  ((bitField0_ & 0x00000004) != 0),
                   getParentForChildren(),
                   isClean());
           links_ = null;
@@ -12194,7 +12169,7 @@ private Instruction(com.google.protobuf.GeneratedMessageV3.Builder builder) {
     }
     private Instruction() {
       instanceid_ = com.google.protobuf.ByteString.EMPTY;
-      signercounter_ = java.util.Collections.emptyList();
+      signercounter_ = emptyLongList();
       signeridentities_ = java.util.Collections.emptyList();
       signatures_ = java.util.Collections.emptyList();
     }
@@ -12230,7 +12205,7 @@ private Instruction(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = spawn_.toBuilder();
               }
               spawn_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn.parser(), extensionRegistry);
@@ -12243,7 +12218,7 @@ private Instruction(
             }
             case 26: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (((bitField0_ & 0x00000004) != 0)) {
                 subBuilder = invoke_.toBuilder();
               }
               invoke_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke.parser(), extensionRegistry);
@@ -12256,7 +12231,7 @@ private Instruction(
             }
             case 34: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Delete.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000008) == 0x00000008)) {
+              if (((bitField0_ & 0x00000008) != 0)) {
                 subBuilder = delete_.toBuilder();
               }
               delete_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Delete.parser(), extensionRegistry);
@@ -12268,28 +12243,28 @@ private Instruction(
               break;
             }
             case 40: {
-              if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
-                signercounter_ = new java.util.ArrayList();
+              if (!((mutable_bitField0_ & 0x00000010) != 0)) {
+                signercounter_ = newLongList();
                 mutable_bitField0_ |= 0x00000010;
               }
-              signercounter_.add(input.readUInt64());
+              signercounter_.addLong(input.readUInt64());
               break;
             }
             case 42: {
               int length = input.readRawVarint32();
               int limit = input.pushLimit(length);
-              if (!((mutable_bitField0_ & 0x00000010) == 0x00000010) && input.getBytesUntilLimit() > 0) {
-                signercounter_ = new java.util.ArrayList();
+              if (!((mutable_bitField0_ & 0x00000010) != 0) && input.getBytesUntilLimit() > 0) {
+                signercounter_ = newLongList();
                 mutable_bitField0_ |= 0x00000010;
               }
               while (input.getBytesUntilLimit() > 0) {
-                signercounter_.add(input.readUInt64());
+                signercounter_.addLong(input.readUInt64());
               }
               input.popLimit(limit);
               break;
             }
             case 50: {
-              if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+              if (!((mutable_bitField0_ & 0x00000020) != 0)) {
                 signeridentities_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000020;
               }
@@ -12298,7 +12273,7 @@ private Instruction(
               break;
             }
             case 58: {
-              if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
+              if (!((mutable_bitField0_ & 0x00000040) != 0)) {
                 signatures_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000040;
               }
@@ -12320,14 +12295,14 @@ private Instruction(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
-          signercounter_ = java.util.Collections.unmodifiableList(signercounter_);
+        if (((mutable_bitField0_ & 0x00000010) != 0)) {
+          signercounter_.makeImmutable(); // C
         }
-        if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+        if (((mutable_bitField0_ & 0x00000020) != 0)) {
           signeridentities_ = java.util.Collections.unmodifiableList(signeridentities_);
         }
-        if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
-          signatures_ = java.util.Collections.unmodifiableList(signatures_);
+        if (((mutable_bitField0_ & 0x00000040) != 0)) {
+          signatures_ = java.util.Collections.unmodifiableList(signatures_); // C
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -12358,7 +12333,7 @@ private Instruction(
      * required bytes instanceid = 1;
      */
     public boolean hasInstanceid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -12382,7 +12357,7 @@ public com.google.protobuf.ByteString getInstanceid() {
      * optional .byzcoin.Spawn spawn = 2;
      */
     public boolean hasSpawn() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -12415,7 +12390,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.SpawnOrBuilder getSpawnOrBuilder() {
      * optional .byzcoin.Invoke invoke = 3;
      */
     public boolean hasInvoke() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -12448,7 +12423,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.InvokeOrBuilder getInvokeOrBuilder()
      * optional .byzcoin.Delete delete = 4;
      */
     public boolean hasDelete() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * 
@@ -12472,7 +12447,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DeleteOrBuilder getDeleteOrBuilder()
     }
 
     public static final int SIGNERCOUNTER_FIELD_NUMBER = 5;
-    private java.util.List signercounter_;
+    private com.google.protobuf.Internal.LongList signercounter_;
     /**
      * 
      * SignerCounter must be set to a value that is one greater than what
@@ -12511,7 +12486,7 @@ public int getSignercounterCount() {
      * repeated uint64 signercounter = 5 [packed = true];
      */
     public long getSignercounter(int index) {
-      return signercounter_.get(index);
+      return signercounter_.getLong(index);
     }
     private int signercounterMemoizedSerializedSize = -1;
 
@@ -12650,16 +12625,16 @@ public final boolean isInitialized() {
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
       getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, instanceid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getSpawn());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeMessage(3, getInvoke());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeMessage(4, getDelete());
       }
       if (getSignercounterList().size() > 0) {
@@ -12667,7 +12642,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
         output.writeUInt32NoTag(signercounterMemoizedSerializedSize);
       }
       for (int i = 0; i < signercounter_.size(); i++) {
-        output.writeUInt64NoTag(signercounter_.get(i));
+        output.writeUInt64NoTag(signercounter_.getLong(i));
       }
       for (int i = 0; i < signeridentities_.size(); i++) {
         output.writeMessage(6, signeridentities_.get(i));
@@ -12684,19 +12659,19 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, instanceid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getSpawn());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getInvoke());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(4, getDelete());
       }
@@ -12704,7 +12679,7 @@ public int getSerializedSize() {
         int dataSize = 0;
         for (int i = 0; i < signercounter_.size(); i++) {
           dataSize += com.google.protobuf.CodedOutputStream
-            .computeUInt64SizeNoTag(signercounter_.get(i));
+            .computeUInt64SizeNoTag(signercounter_.getLong(i));
         }
         size += dataSize;
         if (!getSignercounterList().isEmpty()) {
@@ -12742,35 +12717,34 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.Instruction other = (ch.epfl.dedis.lib.proto.ByzCoinProto.Instruction) obj;
 
-      boolean result = true;
-      result = result && (hasInstanceid() == other.hasInstanceid());
+      if (hasInstanceid() != other.hasInstanceid()) return false;
       if (hasInstanceid()) {
-        result = result && getInstanceid()
-            .equals(other.getInstanceid());
+        if (!getInstanceid()
+            .equals(other.getInstanceid())) return false;
       }
-      result = result && (hasSpawn() == other.hasSpawn());
+      if (hasSpawn() != other.hasSpawn()) return false;
       if (hasSpawn()) {
-        result = result && getSpawn()
-            .equals(other.getSpawn());
+        if (!getSpawn()
+            .equals(other.getSpawn())) return false;
       }
-      result = result && (hasInvoke() == other.hasInvoke());
+      if (hasInvoke() != other.hasInvoke()) return false;
       if (hasInvoke()) {
-        result = result && getInvoke()
-            .equals(other.getInvoke());
+        if (!getInvoke()
+            .equals(other.getInvoke())) return false;
       }
-      result = result && (hasDelete() == other.hasDelete());
+      if (hasDelete() != other.hasDelete()) return false;
       if (hasDelete()) {
-        result = result && getDelete()
-            .equals(other.getDelete());
-      }
-      result = result && getSignercounterList()
-          .equals(other.getSignercounterList());
-      result = result && getSigneridentitiesList()
-          .equals(other.getSigneridentitiesList());
-      result = result && getSignaturesList()
-          .equals(other.getSignaturesList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+        if (!getDelete()
+            .equals(other.getDelete())) return false;
+      }
+      if (!getSignercounterList()
+          .equals(other.getSignercounterList())) return false;
+      if (!getSigneridentitiesList()
+          .equals(other.getSigneridentitiesList())) return false;
+      if (!getSignaturesList()
+          .equals(other.getSignaturesList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -12969,7 +12943,7 @@ public Builder clear() {
           deleteBuilder_.clear();
         }
         bitField0_ = (bitField0_ & ~0x00000008);
-        signercounter_ = java.util.Collections.emptyList();
+        signercounter_ = emptyLongList();
         bitField0_ = (bitField0_ & ~0x00000010);
         if (signeridentitiesBuilder_ == null) {
           signeridentities_ = java.util.Collections.emptyList();
@@ -13007,41 +12981,41 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Instruction buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.Instruction result = new ch.epfl.dedis.lib.proto.ByzCoinProto.Instruction(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.instanceid_ = instanceid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (spawnBuilder_ == null) {
+            result.spawn_ = spawn_;
+          } else {
+            result.spawn_ = spawnBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (spawnBuilder_ == null) {
-          result.spawn_ = spawn_;
-        } else {
-          result.spawn_ = spawnBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          if (invokeBuilder_ == null) {
+            result.invoke_ = invoke_;
+          } else {
+            result.invoke_ = invokeBuilder_.build();
+          }
           to_bitField0_ |= 0x00000004;
         }
-        if (invokeBuilder_ == null) {
-          result.invoke_ = invoke_;
-        } else {
-          result.invoke_ = invokeBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          if (deleteBuilder_ == null) {
+            result.delete_ = delete_;
+          } else {
+            result.delete_ = deleteBuilder_.build();
+          }
           to_bitField0_ |= 0x00000008;
         }
-        if (deleteBuilder_ == null) {
-          result.delete_ = delete_;
-        } else {
-          result.delete_ = deleteBuilder_.build();
-        }
-        if (((bitField0_ & 0x00000010) == 0x00000010)) {
-          signercounter_ = java.util.Collections.unmodifiableList(signercounter_);
+        if (((bitField0_ & 0x00000010) != 0)) {
+          signercounter_.makeImmutable();
           bitField0_ = (bitField0_ & ~0x00000010);
         }
         result.signercounter_ = signercounter_;
         if (signeridentitiesBuilder_ == null) {
-          if (((bitField0_ & 0x00000020) == 0x00000020)) {
+          if (((bitField0_ & 0x00000020) != 0)) {
             signeridentities_ = java.util.Collections.unmodifiableList(signeridentities_);
             bitField0_ = (bitField0_ & ~0x00000020);
           }
@@ -13049,7 +13023,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Instruction buildPartial() {
         } else {
           result.signeridentities_ = signeridentitiesBuilder_.build();
         }
-        if (((bitField0_ & 0x00000040) == 0x00000040)) {
+        if (((bitField0_ & 0x00000040) != 0)) {
           signatures_ = java.util.Collections.unmodifiableList(signatures_);
           bitField0_ = (bitField0_ & ~0x00000040);
         }
@@ -13061,35 +13035,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Instruction buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -13224,7 +13198,7 @@ public Builder mergeFrom(
        * required bytes instanceid = 1;
        */
       public boolean hasInstanceid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -13269,7 +13243,7 @@ public Builder clearInstanceid() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn spawn_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn spawn_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn, ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.SpawnOrBuilder> spawnBuilder_;
       /**
@@ -13280,7 +13254,7 @@ public Builder clearInstanceid() {
        * optional .byzcoin.Spawn spawn = 2;
        */
       public boolean hasSpawn() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -13343,7 +13317,7 @@ public Builder setSpawn(
        */
       public Builder mergeSpawn(ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn value) {
         if (spawnBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               spawn_ != null &&
               spawn_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn.getDefaultInstance()) {
             spawn_ =
@@ -13423,7 +13397,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.SpawnOrBuilder getSpawnOrBuilder() {
         return spawnBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke invoke_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke invoke_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke, ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.InvokeOrBuilder> invokeBuilder_;
       /**
@@ -13434,7 +13408,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.SpawnOrBuilder getSpawnOrBuilder() {
        * optional .byzcoin.Invoke invoke = 3;
        */
       public boolean hasInvoke() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -13497,7 +13471,7 @@ public Builder setInvoke(
        */
       public Builder mergeInvoke(ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke value) {
         if (invokeBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+          if (((bitField0_ & 0x00000004) != 0) &&
               invoke_ != null &&
               invoke_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke.getDefaultInstance()) {
             invoke_ =
@@ -13577,7 +13551,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.InvokeOrBuilder getInvokeOrBuilder()
         return invokeBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Delete delete_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Delete delete_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Delete, ch.epfl.dedis.lib.proto.ByzCoinProto.Delete.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.DeleteOrBuilder> deleteBuilder_;
       /**
@@ -13588,7 +13562,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.InvokeOrBuilder getInvokeOrBuilder()
        * optional .byzcoin.Delete delete = 4;
        */
       public boolean hasDelete() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * 
@@ -13651,7 +13625,7 @@ public Builder setDelete(
        */
       public Builder mergeDelete(ch.epfl.dedis.lib.proto.ByzCoinProto.Delete value) {
         if (deleteBuilder_ == null) {
-          if (((bitField0_ & 0x00000008) == 0x00000008) &&
+          if (((bitField0_ & 0x00000008) != 0) &&
               delete_ != null &&
               delete_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Delete.getDefaultInstance()) {
             delete_ =
@@ -13731,10 +13705,10 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DeleteOrBuilder getDeleteOrBuilder()
         return deleteBuilder_;
       }
 
-      private java.util.List signercounter_ = java.util.Collections.emptyList();
+      private com.google.protobuf.Internal.LongList signercounter_ = emptyLongList();
       private void ensureSignercounterIsMutable() {
-        if (!((bitField0_ & 0x00000010) == 0x00000010)) {
-          signercounter_ = new java.util.ArrayList(signercounter_);
+        if (!((bitField0_ & 0x00000010) != 0)) {
+          signercounter_ = mutableCopy(signercounter_);
           bitField0_ |= 0x00000010;
          }
       }
@@ -13750,7 +13724,8 @@ private void ensureSignercounterIsMutable() {
        */
       public java.util.List
           getSignercounterList() {
-        return java.util.Collections.unmodifiableList(signercounter_);
+        return ((bitField0_ & 0x00000010) != 0) ?
+                 java.util.Collections.unmodifiableList(signercounter_) : signercounter_;
       }
       /**
        * 
@@ -13776,7 +13751,7 @@ public int getSignercounterCount() {
        * repeated uint64 signercounter = 5 [packed = true];
        */
       public long getSignercounter(int index) {
-        return signercounter_.get(index);
+        return signercounter_.getLong(index);
       }
       /**
        * 
@@ -13791,7 +13766,7 @@ public long getSignercounter(int index) {
       public Builder setSignercounter(
           int index, long value) {
         ensureSignercounterIsMutable();
-        signercounter_.set(index, value);
+        signercounter_.setLong(index, value);
         onChanged();
         return this;
       }
@@ -13807,7 +13782,7 @@ public Builder setSignercounter(
        */
       public Builder addSignercounter(long value) {
         ensureSignercounterIsMutable();
-        signercounter_.add(value);
+        signercounter_.addLong(value);
         onChanged();
         return this;
       }
@@ -13840,7 +13815,7 @@ public Builder addAllSignercounter(
        * repeated uint64 signercounter = 5 [packed = true];
        */
       public Builder clearSignercounter() {
-        signercounter_ = java.util.Collections.emptyList();
+        signercounter_ = emptyLongList();
         bitField0_ = (bitField0_ & ~0x00000010);
         onChanged();
         return this;
@@ -13849,7 +13824,7 @@ public Builder clearSignercounter() {
       private java.util.List signeridentities_ =
         java.util.Collections.emptyList();
       private void ensureSigneridentitiesIsMutable() {
-        if (!((bitField0_ & 0x00000020) == 0x00000020)) {
+        if (!((bitField0_ & 0x00000020) != 0)) {
           signeridentities_ = new java.util.ArrayList(signeridentities_);
           bitField0_ |= 0x00000020;
          }
@@ -14150,7 +14125,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Identity.Builder addSigneridentitiesBui
           signeridentitiesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.DarcProto.Identity, ch.epfl.dedis.lib.proto.DarcProto.Identity.Builder, ch.epfl.dedis.lib.proto.DarcProto.IdentityOrBuilder>(
                   signeridentities_,
-                  ((bitField0_ & 0x00000020) == 0x00000020),
+                  ((bitField0_ & 0x00000020) != 0),
                   getParentForChildren(),
                   isClean());
           signeridentities_ = null;
@@ -14160,7 +14135,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Identity.Builder addSigneridentitiesBui
 
       private java.util.List signatures_ = java.util.Collections.emptyList();
       private void ensureSignaturesIsMutable() {
-        if (!((bitField0_ & 0x00000040) == 0x00000040)) {
+        if (!((bitField0_ & 0x00000040) != 0)) {
           signatures_ = new java.util.ArrayList(signatures_);
           bitField0_ |= 0x00000040;
          }
@@ -14175,7 +14150,8 @@ private void ensureSignaturesIsMutable() {
        */
       public java.util.List
           getSignaturesList() {
-        return java.util.Collections.unmodifiableList(signatures_);
+        return ((bitField0_ & 0x00000040) != 0) ?
+                 java.util.Collections.unmodifiableList(signatures_) : signatures_;
       }
       /**
        * 
@@ -14443,7 +14419,7 @@ private Spawn(
               break;
             }
             case 18: {
-              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
                 args_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000002;
               }
@@ -14466,7 +14442,7 @@ private Spawn(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
           args_ = java.util.Collections.unmodifiableList(args_);
         }
         this.unknownFields = unknownFields.build();
@@ -14497,7 +14473,7 @@ private Spawn(
      * required string contractid = 1;
      */
     public boolean hasContractid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -14620,7 +14596,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, contractid_);
       }
       for (int i = 0; i < args_.size(); i++) {
@@ -14635,7 +14611,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, contractid_);
       }
       for (int i = 0; i < args_.size(); i++) {
@@ -14657,16 +14633,15 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn other = (ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn) obj;
 
-      boolean result = true;
-      result = result && (hasContractid() == other.hasContractid());
+      if (hasContractid() != other.hasContractid()) return false;
       if (hasContractid()) {
-        result = result && getContractid()
-            .equals(other.getContractid());
+        if (!getContractid()
+            .equals(other.getContractid())) return false;
       }
-      result = result && getArgsList()
-          .equals(other.getArgsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getArgsList()
+          .equals(other.getArgsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -14858,12 +14833,12 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn result = new ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.contractid_ = contractid_;
         if (argsBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          if (((bitField0_ & 0x00000002) != 0)) {
             args_ = java.util.Collections.unmodifiableList(args_);
             bitField0_ = (bitField0_ & ~0x00000002);
           }
@@ -14878,35 +14853,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Spawn buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -14998,7 +14973,7 @@ public Builder mergeFrom(
        * required string contractid = 1;
        */
       public boolean hasContractid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -15092,7 +15067,7 @@ public Builder setContractidBytes(
       private java.util.List args_ =
         java.util.Collections.emptyList();
       private void ensureArgsIsMutable() {
-        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+        if (!((bitField0_ & 0x00000002) != 0)) {
           args_ = new java.util.ArrayList(args_);
           bitField0_ |= 0x00000002;
          }
@@ -15393,7 +15368,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Argument.Builder addArgsBuilder(
           argsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.ByzCoinProto.Argument, ch.epfl.dedis.lib.proto.ByzCoinProto.Argument.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ArgumentOrBuilder>(
                   args_,
-                  ((bitField0_ & 0x00000002) == 0x00000002),
+                  ((bitField0_ & 0x00000002) != 0),
                   getParentForChildren(),
                   isClean());
           args_ = null;
@@ -15613,7 +15588,7 @@ private Invoke(
               break;
             }
             case 26: {
-              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+              if (!((mutable_bitField0_ & 0x00000004) != 0)) {
                 args_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000004;
               }
@@ -15636,7 +15611,7 @@ private Invoke(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((mutable_bitField0_ & 0x00000004) != 0)) {
           args_ = java.util.Collections.unmodifiableList(args_);
         }
         this.unknownFields = unknownFields.build();
@@ -15667,7 +15642,7 @@ private Invoke(
      * required string contractid = 1;
      */
     public boolean hasContractid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -15721,7 +15696,7 @@ public java.lang.String getContractid() {
      * required string command = 2;
      */
     public boolean hasCommand() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -15848,10 +15823,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, contractid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 2, command_);
       }
       for (int i = 0; i < args_.size(); i++) {
@@ -15866,10 +15841,10 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, contractid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, command_);
       }
       for (int i = 0; i < args_.size(); i++) {
@@ -15891,21 +15866,20 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke other = (ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke) obj;
 
-      boolean result = true;
-      result = result && (hasContractid() == other.hasContractid());
+      if (hasContractid() != other.hasContractid()) return false;
       if (hasContractid()) {
-        result = result && getContractid()
-            .equals(other.getContractid());
+        if (!getContractid()
+            .equals(other.getContractid())) return false;
       }
-      result = result && (hasCommand() == other.hasCommand());
+      if (hasCommand() != other.hasCommand()) return false;
       if (hasCommand()) {
-        result = result && getCommand()
-            .equals(other.getCommand());
+        if (!getCommand()
+            .equals(other.getCommand())) return false;
       }
-      result = result && getArgsList()
-          .equals(other.getArgsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getArgsList()
+          .equals(other.getArgsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -16104,16 +16078,16 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke result = new ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.contractid_ = contractid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.command_ = command_;
         if (argsBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004)) {
+          if (((bitField0_ & 0x00000004) != 0)) {
             args_ = java.util.Collections.unmodifiableList(args_);
             bitField0_ = (bitField0_ & ~0x00000004);
           }
@@ -16128,35 +16102,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Invoke buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -16256,7 +16230,7 @@ public Builder mergeFrom(
        * required string contractid = 1;
        */
       public boolean hasContractid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -16356,7 +16330,7 @@ public Builder setContractidBytes(
        * required string command = 2;
        */
       public boolean hasCommand() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -16450,7 +16424,7 @@ public Builder setCommandBytes(
       private java.util.List args_ =
         java.util.Collections.emptyList();
       private void ensureArgsIsMutable() {
-        if (!((bitField0_ & 0x00000004) == 0x00000004)) {
+        if (!((bitField0_ & 0x00000004) != 0)) {
           args_ = new java.util.ArrayList(args_);
           bitField0_ |= 0x00000004;
          }
@@ -16751,7 +16725,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Argument.Builder addArgsBuilder(
           argsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.ByzCoinProto.Argument, ch.epfl.dedis.lib.proto.ByzCoinProto.Argument.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ArgumentOrBuilder>(
                   args_,
-                  ((bitField0_ & 0x00000004) == 0x00000004),
+                  ((bitField0_ & 0x00000004) != 0),
                   getParentForChildren(),
                   isClean());
           args_ = null;
@@ -16935,7 +16909,7 @@ private Delete(
      * required string contractid = 1;
      */
     public boolean hasContractid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -16997,7 +16971,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, contractid_);
       }
       unknownFields.writeTo(output);
@@ -17009,7 +16983,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, contractid_);
       }
       size += unknownFields.getSerializedSize();
@@ -17027,14 +17001,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.Delete other = (ch.epfl.dedis.lib.proto.ByzCoinProto.Delete) obj;
 
-      boolean result = true;
-      result = result && (hasContractid() == other.hasContractid());
+      if (hasContractid() != other.hasContractid()) return false;
       if (hasContractid()) {
-        result = result && getContractid()
-            .equals(other.getContractid());
+        if (!getContractid()
+            .equals(other.getContractid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -17216,7 +17189,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Delete buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.Delete result = new ch.epfl.dedis.lib.proto.ByzCoinProto.Delete(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.contractid_ = contractid_;
@@ -17227,35 +17200,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Delete buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -17316,7 +17289,7 @@ public Builder mergeFrom(
        * required string contractid = 1;
        */
       public boolean hasContractid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -17605,7 +17578,7 @@ private Argument(
      * required string name = 1;
      */
     public boolean hasName() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -17659,7 +17632,7 @@ public java.lang.String getName() {
      * required bytes value = 2;
      */
     public boolean hasValue() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -17694,10 +17667,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, value_);
       }
       unknownFields.writeTo(output);
@@ -17709,10 +17682,10 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, value_);
       }
@@ -17731,19 +17704,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.Argument other = (ch.epfl.dedis.lib.proto.ByzCoinProto.Argument) obj;
 
-      boolean result = true;
-      result = result && (hasName() == other.hasName());
+      if (hasName() != other.hasName()) return false;
       if (hasName()) {
-        result = result && getName()
-            .equals(other.getName());
+        if (!getName()
+            .equals(other.getName())) return false;
       }
-      result = result && (hasValue() == other.hasValue());
+      if (hasValue() != other.hasValue()) return false;
       if (hasValue()) {
-        result = result && getValue()
-            .equals(other.getValue());
+        if (!getValue()
+            .equals(other.getValue())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -17930,11 +17902,11 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Argument buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.Argument result = new ch.epfl.dedis.lib.proto.ByzCoinProto.Argument(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.name_ = name_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.value_ = value_;
@@ -17945,35 +17917,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Argument buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -18040,7 +18012,7 @@ public Builder mergeFrom(
        * required string name = 1;
        */
       public boolean hasName() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -18140,7 +18112,7 @@ public Builder setNameBytes(
        * required bytes value = 2;
        */
       public boolean hasValue() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -18311,7 +18283,7 @@ private ClientTransaction(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 instructions_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -18334,7 +18306,7 @@ private ClientTransaction(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           instructions_ = java.util.Collections.unmodifiableList(instructions_);
         }
         this.unknownFields = unknownFields.build();
@@ -18440,11 +18412,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction other = (ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction) obj;
 
-      boolean result = true;
-      result = result && getInstructionsList()
-          .equals(other.getInstructionsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getInstructionsList()
+          .equals(other.getInstructionsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -18634,7 +18605,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction result = new ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction(this);
         int from_bitField0_ = bitField0_;
         if (instructionsBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             instructions_ = java.util.Collections.unmodifiableList(instructions_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -18648,35 +18619,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -18754,7 +18725,7 @@ public Builder mergeFrom(
       private java.util.List instructions_ =
         java.util.Collections.emptyList();
       private void ensureInstructionsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           instructions_ = new java.util.ArrayList(instructions_);
           bitField0_ |= 0x00000001;
          }
@@ -18983,7 +18954,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Instruction.Builder addInstructionsB
           instructionsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.ByzCoinProto.Instruction, ch.epfl.dedis.lib.proto.ByzCoinProto.Instruction.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.InstructionOrBuilder>(
                   instructions_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           instructions_ = null;
@@ -19086,7 +19057,6 @@ private TxResult(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private TxResult() {
-      accepted_ = false;
     }
 
     @java.lang.Override
@@ -19115,7 +19085,7 @@ private TxResult(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = clienttransaction_.toBuilder();
               }
               clienttransaction_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction.parser(), extensionRegistry);
@@ -19170,7 +19140,7 @@ private TxResult(
      * required .byzcoin.ClientTransaction clienttransaction = 1;
      */
     public boolean hasClienttransaction() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required .byzcoin.ClientTransaction clienttransaction = 1;
@@ -19191,7 +19161,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransactionOrBuilder getClient
      * required bool accepted = 2;
      */
     public boolean hasAccepted() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bool accepted = 2;
@@ -19226,10 +19196,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getClienttransaction());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBool(2, accepted_);
       }
       unknownFields.writeTo(output);
@@ -19241,11 +19211,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getClienttransaction());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBoolSize(2, accepted_);
       }
@@ -19264,19 +19234,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.TxResult other = (ch.epfl.dedis.lib.proto.ByzCoinProto.TxResult) obj;
 
-      boolean result = true;
-      result = result && (hasClienttransaction() == other.hasClienttransaction());
+      if (hasClienttransaction() != other.hasClienttransaction()) return false;
       if (hasClienttransaction()) {
-        result = result && getClienttransaction()
-            .equals(other.getClienttransaction());
+        if (!getClienttransaction()
+            .equals(other.getClienttransaction())) return false;
       }
-      result = result && (hasAccepted() == other.hasAccepted());
+      if (hasAccepted() != other.hasAccepted()) return false;
       if (hasAccepted()) {
-        result = result && (getAccepted()
-            == other.getAccepted());
+        if (getAccepted()
+            != other.getAccepted()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -19469,18 +19438,18 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.TxResult buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.TxResult result = new ch.epfl.dedis.lib.proto.ByzCoinProto.TxResult(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (clienttransactionBuilder_ == null) {
+            result.clienttransaction_ = clienttransaction_;
+          } else {
+            result.clienttransaction_ = clienttransactionBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (clienttransactionBuilder_ == null) {
-          result.clienttransaction_ = clienttransaction_;
-        } else {
-          result.clienttransaction_ = clienttransactionBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.accepted_ = accepted_;
           to_bitField0_ |= 0x00000002;
         }
-        result.accepted_ = accepted_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -19488,35 +19457,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.TxResult buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -19575,14 +19544,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction clienttransaction_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction clienttransaction_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction, ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransactionOrBuilder> clienttransactionBuilder_;
       /**
        * required .byzcoin.ClientTransaction clienttransaction = 1;
        */
       public boolean hasClienttransaction() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required .byzcoin.ClientTransaction clienttransaction = 1;
@@ -19629,7 +19598,7 @@ public Builder setClienttransaction(
        */
       public Builder mergeClienttransaction(ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction value) {
         if (clienttransactionBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               clienttransaction_ != null &&
               clienttransaction_ != ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransaction.getDefaultInstance()) {
             clienttransaction_ =
@@ -19698,7 +19667,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.ClientTransactionOrBuilder getClient
        * required bool accepted = 2;
        */
       public boolean hasAccepted() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bool accepted = 2;
@@ -19909,12 +19878,10 @@ private StateChange(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private StateChange() {
-      stateaction_ = 0;
       instanceid_ = com.google.protobuf.ByteString.EMPTY;
       contractid_ = "";
       value_ = com.google.protobuf.ByteString.EMPTY;
       darcid_ = com.google.protobuf.ByteString.EMPTY;
-      version_ = 0L;
     }
 
     @java.lang.Override
@@ -20015,7 +19982,7 @@ private StateChange(
      * required sint32 stateaction = 1;
      */
     public boolean hasStateaction() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -20038,7 +20005,7 @@ public int getStateaction() {
      * required bytes instanceid = 2;
      */
     public boolean hasInstanceid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -20061,7 +20028,7 @@ public com.google.protobuf.ByteString getInstanceid() {
      * required string contractid = 3;
      */
     public boolean hasContractid() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -20115,7 +20082,7 @@ public java.lang.String getContractid() {
      * required bytes value = 4;
      */
     public boolean hasValue() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * 
@@ -20138,7 +20105,7 @@ public com.google.protobuf.ByteString getValue() {
      * required bytes darcid = 5;
      */
     public boolean hasDarcid() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * 
@@ -20161,7 +20128,7 @@ public com.google.protobuf.ByteString getDarcid() {
      * required uint64 version = 6;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000020) == 0x00000020);
+      return ((bitField0_ & 0x00000020) != 0);
     }
     /**
      * 
@@ -20212,22 +20179,22 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, stateaction_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, instanceid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 3, contractid_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeBytes(4, value_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         output.writeBytes(5, darcid_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         output.writeUInt64(6, version_);
       }
       unknownFields.writeTo(output);
@@ -20239,26 +20206,26 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, stateaction_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, instanceid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, contractid_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(4, value_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(5, darcid_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(6, version_);
       }
@@ -20277,39 +20244,38 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange other = (ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange) obj;
 
-      boolean result = true;
-      result = result && (hasStateaction() == other.hasStateaction());
+      if (hasStateaction() != other.hasStateaction()) return false;
       if (hasStateaction()) {
-        result = result && (getStateaction()
-            == other.getStateaction());
+        if (getStateaction()
+            != other.getStateaction()) return false;
       }
-      result = result && (hasInstanceid() == other.hasInstanceid());
+      if (hasInstanceid() != other.hasInstanceid()) return false;
       if (hasInstanceid()) {
-        result = result && getInstanceid()
-            .equals(other.getInstanceid());
+        if (!getInstanceid()
+            .equals(other.getInstanceid())) return false;
       }
-      result = result && (hasContractid() == other.hasContractid());
+      if (hasContractid() != other.hasContractid()) return false;
       if (hasContractid()) {
-        result = result && getContractid()
-            .equals(other.getContractid());
+        if (!getContractid()
+            .equals(other.getContractid())) return false;
       }
-      result = result && (hasValue() == other.hasValue());
+      if (hasValue() != other.hasValue()) return false;
       if (hasValue()) {
-        result = result && getValue()
-            .equals(other.getValue());
+        if (!getValue()
+            .equals(other.getValue())) return false;
       }
-      result = result && (hasDarcid() == other.hasDarcid());
+      if (hasDarcid() != other.hasDarcid()) return false;
       if (hasDarcid()) {
-        result = result && getDarcid()
-            .equals(other.getDarcid());
+        if (!getDarcid()
+            .equals(other.getDarcid())) return false;
       }
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -20521,30 +20487,30 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange result = new ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.stateaction_ = stateaction_;
           to_bitField0_ |= 0x00000001;
         }
-        result.stateaction_ = stateaction_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.instanceid_ = instanceid_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.contractid_ = contractid_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
           to_bitField0_ |= 0x00000008;
         }
         result.value_ = value_;
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((from_bitField0_ & 0x00000010) != 0)) {
           to_bitField0_ |= 0x00000010;
         }
         result.darcid_ = darcid_;
-        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+        if (((from_bitField0_ & 0x00000020) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000020;
         }
-        result.version_ = version_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -20552,35 +20518,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -20671,7 +20637,7 @@ public Builder mergeFrom(
        * required sint32 stateaction = 1;
        */
       public boolean hasStateaction() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -20719,7 +20685,7 @@ public Builder clearStateaction() {
        * required bytes instanceid = 2;
        */
       public boolean hasInstanceid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -20770,7 +20736,7 @@ public Builder clearInstanceid() {
        * required string contractid = 3;
        */
       public boolean hasContractid() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -20870,7 +20836,7 @@ public Builder setContractidBytes(
        * required bytes value = 4;
        */
       public boolean hasValue() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * 
@@ -20921,7 +20887,7 @@ public Builder clearValue() {
        * required bytes darcid = 5;
        */
       public boolean hasDarcid() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return ((bitField0_ & 0x00000010) != 0);
       }
       /**
        * 
@@ -20972,7 +20938,7 @@ public Builder clearDarcid() {
        * required uint64 version = 6;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000020) == 0x00000020);
+        return ((bitField0_ & 0x00000020) != 0);
       }
       /**
        * 
@@ -21120,7 +21086,6 @@ private Coin(com.google.protobuf.GeneratedMessageV3.Builder builder) {
     }
     private Coin() {
       name_ = com.google.protobuf.ByteString.EMPTY;
-      value_ = 0L;
     }
 
     @java.lang.Override
@@ -21200,7 +21165,7 @@ private Coin(
      * required bytes name = 1;
      */
     public boolean hasName() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -21223,7 +21188,7 @@ public com.google.protobuf.ByteString getName() {
      * required uint64 value = 2;
      */
     public boolean hasValue() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -21258,10 +21223,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeUInt64(2, value_);
       }
       unknownFields.writeTo(output);
@@ -21273,11 +21238,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(2, value_);
       }
@@ -21296,19 +21261,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.Coin other = (ch.epfl.dedis.lib.proto.ByzCoinProto.Coin) obj;
 
-      boolean result = true;
-      result = result && (hasName() == other.hasName());
+      if (hasName() != other.hasName()) return false;
       if (hasName()) {
-        result = result && getName()
-            .equals(other.getName());
+        if (!getName()
+            .equals(other.getName())) return false;
       }
-      result = result && (hasValue() == other.hasValue());
+      if (hasValue() != other.hasValue()) return false;
       if (hasValue()) {
-        result = result && (getValue()
-            == other.getValue());
+        if (getValue()
+            != other.getValue()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -21497,14 +21461,14 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Coin buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.Coin result = new ch.epfl.dedis.lib.proto.ByzCoinProto.Coin(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.name_ = name_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.value_ = value_;
           to_bitField0_ |= 0x00000002;
         }
-        result.value_ = value_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -21512,35 +21476,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.Coin buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -21605,7 +21569,7 @@ public Builder mergeFrom(
        * required bytes name = 1;
        */
       public boolean hasName() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -21656,7 +21620,7 @@ public Builder clearName() {
        * required uint64 value = 2;
        */
       public boolean hasValue() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -21849,7 +21813,7 @@ private StreamingRequest(
      * required bytes id = 1;
      */
     public boolean hasId() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes id = 1;
@@ -21876,7 +21840,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, id_);
       }
       unknownFields.writeTo(output);
@@ -21888,7 +21852,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, id_);
       }
@@ -21907,14 +21871,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingRequest other = (ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingRequest) obj;
 
-      boolean result = true;
-      result = result && (hasId() == other.hasId());
+      if (hasId() != other.hasId()) return false;
       if (hasId()) {
-        result = result && getId()
-            .equals(other.getId());
+        if (!getId()
+            .equals(other.getId())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -22096,7 +22059,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingRequest buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingRequest result = new ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingRequest(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.id_ = id_;
@@ -22107,35 +22070,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingRequest buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -22190,7 +22153,7 @@ public Builder mergeFrom(
        * required bytes id = 1;
        */
       public boolean hasId() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes id = 1;
@@ -22334,7 +22297,7 @@ private StreamingResponse(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = block_.toBuilder();
               }
               block_ = input.readMessage(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.parser(), extensionRegistry);
@@ -22384,7 +22347,7 @@ private StreamingResponse(
      * optional .skipchain.SkipBlock block = 1;
      */
     public boolean hasBlock() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * optional .skipchain.SkipBlock block = 1;
@@ -22419,7 +22382,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getBlock());
       }
       unknownFields.writeTo(output);
@@ -22431,7 +22394,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getBlock());
       }
@@ -22450,14 +22413,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingResponse other = (ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingResponse) obj;
 
-      boolean result = true;
-      result = result && (hasBlock() == other.hasBlock());
+      if (hasBlock() != other.hasBlock()) return false;
       if (hasBlock()) {
-        result = result && getBlock()
-            .equals(other.getBlock());
+        if (!getBlock()
+            .equals(other.getBlock())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -22643,14 +22605,14 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingResponse buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingResponse result = new ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingResponse(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (blockBuilder_ == null) {
+            result.block_ = block_;
+          } else {
+            result.block_ = blockBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (blockBuilder_ == null) {
-          result.block_ = block_;
-        } else {
-          result.block_ = blockBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -22658,35 +22620,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StreamingResponse buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -22738,14 +22700,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock block_ = null;
+      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock block_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder> blockBuilder_;
       /**
        * optional .skipchain.SkipBlock block = 1;
        */
       public boolean hasBlock() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * optional .skipchain.SkipBlock block = 1;
@@ -22792,7 +22754,7 @@ public Builder setBlock(
        */
       public Builder mergeBlock(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock value) {
         if (blockBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               block_ != null &&
               block_ != ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.getDefaultInstance()) {
             block_ =
@@ -22994,8 +22956,6 @@ private DownloadState(com.google.protobuf.GeneratedMessageV3.Builder builder)
     }
     private DownloadState() {
       byzcoinid_ = com.google.protobuf.ByteString.EMPTY;
-      nonce_ = 0L;
-      length_ = 0;
     }
 
     @java.lang.Override
@@ -23080,7 +23040,7 @@ private DownloadState(
      * required bytes byzcoinid = 1;
      */
     public boolean hasByzcoinid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -23108,7 +23068,7 @@ public com.google.protobuf.ByteString getByzcoinid() {
      * required uint64 nonce = 2;
      */
     public boolean hasNonce() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -23136,7 +23096,7 @@ public long getNonce() {
      * required sint32 length = 3;
      */
     public boolean hasLength() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -23175,13 +23135,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeUInt64(2, nonce_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeSInt32(3, length_);
       }
       unknownFields.writeTo(output);
@@ -23193,15 +23153,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(2, nonce_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(3, length_);
       }
@@ -23220,24 +23180,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.DownloadState other = (ch.epfl.dedis.lib.proto.ByzCoinProto.DownloadState) obj;
 
-      boolean result = true;
-      result = result && (hasByzcoinid() == other.hasByzcoinid());
+      if (hasByzcoinid() != other.hasByzcoinid()) return false;
       if (hasByzcoinid()) {
-        result = result && getByzcoinid()
-            .equals(other.getByzcoinid());
+        if (!getByzcoinid()
+            .equals(other.getByzcoinid())) return false;
       }
-      result = result && (hasNonce() == other.hasNonce());
+      if (hasNonce() != other.hasNonce()) return false;
       if (hasNonce()) {
-        result = result && (getNonce()
-            == other.getNonce());
+        if (getNonce()
+            != other.getNonce()) return false;
       }
-      result = result && (hasLength() == other.hasLength());
+      if (hasLength() != other.hasLength()) return false;
       if (hasLength()) {
-        result = result && (getLength()
-            == other.getLength());
+        if (getLength()
+            != other.getLength()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -23434,18 +23393,18 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DownloadState buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.DownloadState result = new ch.epfl.dedis.lib.proto.ByzCoinProto.DownloadState(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.byzcoinid_ = byzcoinid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.nonce_ = nonce_;
           to_bitField0_ |= 0x00000002;
         }
-        result.nonce_ = nonce_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          result.length_ = length_;
           to_bitField0_ |= 0x00000004;
         }
-        result.length_ = length_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -23453,35 +23412,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DownloadState buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -23552,7 +23511,7 @@ public Builder mergeFrom(
        * required bytes byzcoinid = 1;
        */
       public boolean hasByzcoinid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -23608,7 +23567,7 @@ public Builder clearByzcoinid() {
        * required uint64 nonce = 2;
        */
       public boolean hasNonce() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -23671,7 +23630,7 @@ public Builder clearNonce() {
        * required sint32 length = 3;
        */
       public boolean hasLength() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -23855,7 +23814,6 @@ private DownloadStateResponse(com.google.protobuf.GeneratedMessageV3.Builder
     }
     private DownloadStateResponse() {
       keyvalues_ = java.util.Collections.emptyList();
-      nonce_ = 0L;
     }
 
     @java.lang.Override
@@ -23883,7 +23841,7 @@ private DownloadStateResponse(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 keyvalues_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -23911,7 +23869,7 @@ private DownloadStateResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           keyvalues_ = java.util.Collections.unmodifiableList(keyvalues_);
         }
         this.unknownFields = unknownFields.build();
@@ -24004,7 +23962,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValueOrBuilder getKeyvaluesOrBu
      * required uint64 nonce = 2;
      */
     public boolean hasNonce() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -24046,7 +24004,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
       for (int i = 0; i < keyvalues_.size(); i++) {
         output.writeMessage(1, keyvalues_.get(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeUInt64(2, nonce_);
       }
       unknownFields.writeTo(output);
@@ -24062,7 +24020,7 @@ public int getSerializedSize() {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, keyvalues_.get(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(2, nonce_);
       }
@@ -24081,16 +24039,15 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.DownloadStateResponse other = (ch.epfl.dedis.lib.proto.ByzCoinProto.DownloadStateResponse) obj;
 
-      boolean result = true;
-      result = result && getKeyvaluesList()
-          .equals(other.getKeyvaluesList());
-      result = result && (hasNonce() == other.hasNonce());
+      if (!getKeyvaluesList()
+          .equals(other.getKeyvaluesList())) return false;
+      if (hasNonce() != other.hasNonce()) return false;
       if (hasNonce()) {
-        result = result && (getNonce()
-            == other.getNonce());
+        if (getNonce()
+            != other.getNonce()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -24285,7 +24242,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DownloadStateResponse buildPartial()
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
         if (keyvaluesBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             keyvalues_ = java.util.Collections.unmodifiableList(keyvalues_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -24293,10 +24250,10 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DownloadStateResponse buildPartial()
         } else {
           result.keyvalues_ = keyvaluesBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.nonce_ = nonce_;
           to_bitField0_ |= 0x00000001;
         }
-        result.nonce_ = nonce_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -24304,35 +24261,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DownloadStateResponse buildPartial()
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -24416,7 +24373,7 @@ public Builder mergeFrom(
       private java.util.List keyvalues_ =
         java.util.Collections.emptyList();
       private void ensureKeyvaluesIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           keyvalues_ = new java.util.ArrayList(keyvalues_);
           bitField0_ |= 0x00000001;
          }
@@ -24735,7 +24692,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValue.Builder addKeyvaluesBuild
           keyvaluesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValue, ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValue.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValueOrBuilder>(
                   keyvalues_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           keyvalues_ = null;
@@ -24754,7 +24711,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValue.Builder addKeyvaluesBuild
        * required uint64 nonce = 2;
        */
       public boolean hasNonce() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -24967,7 +24924,7 @@ private DBKeyValue(
      * required bytes key = 1;
      */
     public boolean hasKey() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes key = 1;
@@ -24982,7 +24939,7 @@ public com.google.protobuf.ByteString getKey() {
      * required bytes value = 2;
      */
     public boolean hasValue() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes value = 2;
@@ -25013,10 +24970,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, key_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, value_);
       }
       unknownFields.writeTo(output);
@@ -25028,11 +24985,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, key_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, value_);
       }
@@ -25051,19 +25008,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValue other = (ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValue) obj;
 
-      boolean result = true;
-      result = result && (hasKey() == other.hasKey());
+      if (hasKey() != other.hasKey()) return false;
       if (hasKey()) {
-        result = result && getKey()
-            .equals(other.getKey());
+        if (!getKey()
+            .equals(other.getKey())) return false;
       }
-      result = result && (hasValue() == other.hasValue());
+      if (hasValue() != other.hasValue()) return false;
       if (hasValue()) {
-        result = result && getValue()
-            .equals(other.getValue());
+        if (!getValue()
+            .equals(other.getValue())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -25250,11 +25206,11 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValue buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValue result = new ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValue(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.key_ = key_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.value_ = value_;
@@ -25265,35 +25221,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DBKeyValue buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -25354,7 +25310,7 @@ public Builder mergeFrom(
        * required bytes key = 1;
        */
       public boolean hasKey() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes key = 1;
@@ -25389,7 +25345,7 @@ public Builder clearKey() {
        * required bytes value = 2;
        */
       public boolean hasValue() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes value = 2;
@@ -25543,10 +25499,8 @@ private StateChangeBody(com.google.protobuf.GeneratedMessageV3.Builder builde
       super(builder);
     }
     private StateChangeBody() {
-      stateaction_ = 0;
       contractid_ = "";
       value_ = com.google.protobuf.ByteString.EMPTY;
-      version_ = 0L;
       darcid_ = com.google.protobuf.ByteString.EMPTY;
     }
 
@@ -25639,7 +25593,7 @@ private StateChangeBody(
      * required sint32 stateaction = 1;
      */
     public boolean hasStateaction() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required sint32 stateaction = 1;
@@ -25654,7 +25608,7 @@ public int getStateaction() {
      * required string contractid = 2;
      */
     public boolean hasContractid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required string contractid = 2;
@@ -25696,7 +25650,7 @@ public java.lang.String getContractid() {
      * required bytes value = 3;
      */
     public boolean hasValue() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required bytes value = 3;
@@ -25711,7 +25665,7 @@ public com.google.protobuf.ByteString getValue() {
      * required uint64 version = 4;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * required uint64 version = 4;
@@ -25726,7 +25680,7 @@ public long getVersion() {
      * required bytes darcid = 5;
      */
     public boolean hasDarcid() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * required bytes darcid = 5;
@@ -25769,19 +25723,19 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, stateaction_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 2, contractid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, value_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeUInt64(4, version_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         output.writeBytes(5, darcid_);
       }
       unknownFields.writeTo(output);
@@ -25793,22 +25747,22 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, stateaction_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, contractid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, value_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(4, version_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(5, darcid_);
       }
@@ -25827,34 +25781,33 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody other = (ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody) obj;
 
-      boolean result = true;
-      result = result && (hasStateaction() == other.hasStateaction());
+      if (hasStateaction() != other.hasStateaction()) return false;
       if (hasStateaction()) {
-        result = result && (getStateaction()
-            == other.getStateaction());
+        if (getStateaction()
+            != other.getStateaction()) return false;
       }
-      result = result && (hasContractid() == other.hasContractid());
+      if (hasContractid() != other.hasContractid()) return false;
       if (hasContractid()) {
-        result = result && getContractid()
-            .equals(other.getContractid());
+        if (!getContractid()
+            .equals(other.getContractid())) return false;
       }
-      result = result && (hasValue() == other.hasValue());
+      if (hasValue() != other.hasValue()) return false;
       if (hasValue()) {
-        result = result && getValue()
-            .equals(other.getValue());
+        if (!getValue()
+            .equals(other.getValue())) return false;
       }
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && (hasDarcid() == other.hasDarcid());
+      if (hasDarcid() != other.hasDarcid()) return false;
       if (hasDarcid()) {
-        result = result && getDarcid()
-            .equals(other.getDarcid());
+        if (!getDarcid()
+            .equals(other.getDarcid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -26061,23 +26014,23 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody result = new ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.stateaction_ = stateaction_;
           to_bitField0_ |= 0x00000001;
         }
-        result.stateaction_ = stateaction_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.contractid_ = contractid_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.value_ = value_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000008;
         }
-        result.version_ = version_;
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((from_bitField0_ & 0x00000010) != 0)) {
           to_bitField0_ |= 0x00000010;
         }
         result.darcid_ = darcid_;
@@ -26088,35 +26041,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -26197,7 +26150,7 @@ public Builder mergeFrom(
        * required sint32 stateaction = 1;
        */
       public boolean hasStateaction() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required sint32 stateaction = 1;
@@ -26229,7 +26182,7 @@ public Builder clearStateaction() {
        * required string contractid = 2;
        */
       public boolean hasContractid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required string contractid = 2;
@@ -26305,7 +26258,7 @@ public Builder setContractidBytes(
        * required bytes value = 3;
        */
       public boolean hasValue() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required bytes value = 3;
@@ -26340,7 +26293,7 @@ public Builder clearValue() {
        * required uint64 version = 4;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * required uint64 version = 4;
@@ -26372,7 +26325,7 @@ public Builder clearVersion() {
        * required bytes darcid = 5;
        */
       public boolean hasDarcid() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return ((bitField0_ & 0x00000010) != 0);
       }
       /**
        * required bytes darcid = 5;
@@ -26534,7 +26487,7 @@ private GetSignerCounters(
               break;
             case 10: {
               com.google.protobuf.ByteString bs = input.readBytes();
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 signerids_ = new com.google.protobuf.LazyStringArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -26561,7 +26514,7 @@ private GetSignerCounters(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           signerids_ = signerids_.getUnmodifiableView();
         }
         this.unknownFields = unknownFields.build();
@@ -26617,7 +26570,7 @@ public java.lang.String getSignerids(int index) {
      * required bytes skipchainid = 2;
      */
     public boolean hasSkipchainid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes skipchainid = 2;
@@ -26647,7 +26600,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
       for (int i = 0; i < signerids_.size(); i++) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, signerids_.getRaw(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(2, skipchainid_);
       }
       unknownFields.writeTo(output);
@@ -26667,7 +26620,7 @@ public int getSerializedSize() {
         size += dataSize;
         size += 1 * getSigneridsList().size();
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, skipchainid_);
       }
@@ -26686,16 +26639,15 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCounters other = (ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCounters) obj;
 
-      boolean result = true;
-      result = result && getSigneridsList()
-          .equals(other.getSigneridsList());
-      result = result && (hasSkipchainid() == other.hasSkipchainid());
+      if (!getSigneridsList()
+          .equals(other.getSigneridsList())) return false;
+      if (hasSkipchainid() != other.hasSkipchainid()) return false;
       if (hasSkipchainid()) {
-        result = result && getSkipchainid()
-            .equals(other.getSkipchainid());
+        if (!getSkipchainid()
+            .equals(other.getSkipchainid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -26883,12 +26835,12 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCounters buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCounters result = new ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCounters(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((bitField0_ & 0x00000001) != 0)) {
           signerids_ = signerids_.getUnmodifiableView();
           bitField0_ = (bitField0_ & ~0x00000001);
         }
         result.signerids_ = signerids_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.skipchainid_ = skipchainid_;
@@ -26899,35 +26851,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCounters buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -26989,7 +26941,7 @@ public Builder mergeFrom(
 
       private com.google.protobuf.LazyStringList signerids_ = com.google.protobuf.LazyStringArrayList.EMPTY;
       private void ensureSigneridsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           signerids_ = new com.google.protobuf.LazyStringArrayList(signerids_);
           bitField0_ |= 0x00000001;
          }
@@ -27085,7 +27037,7 @@ public Builder addSigneridsBytes(
        * required bytes skipchainid = 2;
        */
       public boolean hasSkipchainid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes skipchainid = 2;
@@ -27202,7 +27154,7 @@ private GetSignerCountersResponse(com.google.protobuf.GeneratedMessageV3.Builder
       super(builder);
     }
     private GetSignerCountersResponse() {
-      counters_ = java.util.Collections.emptyList();
+      counters_ = emptyLongList();
     }
 
     @java.lang.Override
@@ -27230,22 +27182,22 @@ private GetSignerCountersResponse(
               done = true;
               break;
             case 8: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-                counters_ = new java.util.ArrayList();
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                counters_ = newLongList();
                 mutable_bitField0_ |= 0x00000001;
               }
-              counters_.add(input.readUInt64());
+              counters_.addLong(input.readUInt64());
               break;
             }
             case 10: {
               int length = input.readRawVarint32();
               int limit = input.pushLimit(length);
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001) && input.getBytesUntilLimit() > 0) {
-                counters_ = new java.util.ArrayList();
+              if (!((mutable_bitField0_ & 0x00000001) != 0) && input.getBytesUntilLimit() > 0) {
+                counters_ = newLongList();
                 mutable_bitField0_ |= 0x00000001;
               }
               while (input.getBytesUntilLimit() > 0) {
-                counters_.add(input.readUInt64());
+                counters_.addLong(input.readUInt64());
               }
               input.popLimit(limit);
               break;
@@ -27265,8 +27217,8 @@ private GetSignerCountersResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-          counters_ = java.util.Collections.unmodifiableList(counters_);
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          counters_.makeImmutable(); // C
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -27286,7 +27238,7 @@ private GetSignerCountersResponse(
     }
 
     public static final int COUNTERS_FIELD_NUMBER = 1;
-    private java.util.List counters_;
+    private com.google.protobuf.Internal.LongList counters_;
     /**
      * repeated uint64 counters = 1 [packed = true];
      */
@@ -27304,7 +27256,7 @@ public int getCountersCount() {
      * repeated uint64 counters = 1 [packed = true];
      */
     public long getCounters(int index) {
-      return counters_.get(index);
+      return counters_.getLong(index);
     }
     private int countersMemoizedSerializedSize = -1;
 
@@ -27328,7 +27280,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
         output.writeUInt32NoTag(countersMemoizedSerializedSize);
       }
       for (int i = 0; i < counters_.size(); i++) {
-        output.writeUInt64NoTag(counters_.get(i));
+        output.writeUInt64NoTag(counters_.getLong(i));
       }
       unknownFields.writeTo(output);
     }
@@ -27343,7 +27295,7 @@ public int getSerializedSize() {
         int dataSize = 0;
         for (int i = 0; i < counters_.size(); i++) {
           dataSize += com.google.protobuf.CodedOutputStream
-            .computeUInt64SizeNoTag(counters_.get(i));
+            .computeUInt64SizeNoTag(counters_.getLong(i));
         }
         size += dataSize;
         if (!getCountersList().isEmpty()) {
@@ -27368,11 +27320,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCountersResponse other = (ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCountersResponse) obj;
 
-      boolean result = true;
-      result = result && getCountersList()
-          .equals(other.getCountersList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getCountersList()
+          .equals(other.getCountersList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -27524,7 +27475,7 @@ private void maybeForceBuilderInitialization() {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        counters_ = java.util.Collections.emptyList();
+        counters_ = emptyLongList();
         bitField0_ = (bitField0_ & ~0x00000001);
         return this;
       }
@@ -27553,8 +27504,8 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCountersResponse build() {
       public ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCountersResponse buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCountersResponse result = new ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCountersResponse(this);
         int from_bitField0_ = bitField0_;
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
-          counters_ = java.util.Collections.unmodifiableList(counters_);
+        if (((bitField0_ & 0x00000001) != 0)) {
+          counters_.makeImmutable();
           bitField0_ = (bitField0_ & ~0x00000001);
         }
         result.counters_ = counters_;
@@ -27564,35 +27515,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetSignerCountersResponse buildParti
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -27646,10 +27597,10 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private java.util.List counters_ = java.util.Collections.emptyList();
+      private com.google.protobuf.Internal.LongList counters_ = emptyLongList();
       private void ensureCountersIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
-          counters_ = new java.util.ArrayList(counters_);
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          counters_ = mutableCopy(counters_);
           bitField0_ |= 0x00000001;
          }
       }
@@ -27658,7 +27609,8 @@ private void ensureCountersIsMutable() {
        */
       public java.util.List
           getCountersList() {
-        return java.util.Collections.unmodifiableList(counters_);
+        return ((bitField0_ & 0x00000001) != 0) ?
+                 java.util.Collections.unmodifiableList(counters_) : counters_;
       }
       /**
        * repeated uint64 counters = 1 [packed = true];
@@ -27670,7 +27622,7 @@ public int getCountersCount() {
        * repeated uint64 counters = 1 [packed = true];
        */
       public long getCounters(int index) {
-        return counters_.get(index);
+        return counters_.getLong(index);
       }
       /**
        * repeated uint64 counters = 1 [packed = true];
@@ -27678,7 +27630,7 @@ public long getCounters(int index) {
       public Builder setCounters(
           int index, long value) {
         ensureCountersIsMutable();
-        counters_.set(index, value);
+        counters_.setLong(index, value);
         onChanged();
         return this;
       }
@@ -27687,7 +27639,7 @@ public Builder setCounters(
        */
       public Builder addCounters(long value) {
         ensureCountersIsMutable();
-        counters_.add(value);
+        counters_.addLong(value);
         onChanged();
         return this;
       }
@@ -27706,7 +27658,7 @@ public Builder addAllCounters(
        * repeated uint64 counters = 1 [packed = true];
        */
       public Builder clearCounters() {
-        counters_ = java.util.Collections.emptyList();
+        counters_ = emptyLongList();
         bitField0_ = (bitField0_ & ~0x00000001);
         onChanged();
         return this;
@@ -27815,7 +27767,6 @@ private GetInstanceVersion(com.google.protobuf.GeneratedMessageV3.Builder bui
     private GetInstanceVersion() {
       skipchainid_ = com.google.protobuf.ByteString.EMPTY;
       instanceid_ = com.google.protobuf.ByteString.EMPTY;
-      version_ = 0L;
     }
 
     @java.lang.Override
@@ -27896,7 +27847,7 @@ private GetInstanceVersion(
      * required bytes skipchainid = 1;
      */
     public boolean hasSkipchainid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes skipchainid = 1;
@@ -27911,7 +27862,7 @@ public com.google.protobuf.ByteString getSkipchainid() {
      * required bytes instanceid = 2;
      */
     public boolean hasInstanceid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes instanceid = 2;
@@ -27926,7 +27877,7 @@ public com.google.protobuf.ByteString getInstanceid() {
      * required uint64 version = 3;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required uint64 version = 3;
@@ -27961,13 +27912,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, skipchainid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, instanceid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeUInt64(3, version_);
       }
       unknownFields.writeTo(output);
@@ -27979,15 +27930,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, skipchainid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, instanceid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(3, version_);
       }
@@ -28006,24 +27957,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersion other = (ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersion) obj;
 
-      boolean result = true;
-      result = result && (hasSkipchainid() == other.hasSkipchainid());
+      if (hasSkipchainid() != other.hasSkipchainid()) return false;
       if (hasSkipchainid()) {
-        result = result && getSkipchainid()
-            .equals(other.getSkipchainid());
+        if (!getSkipchainid()
+            .equals(other.getSkipchainid())) return false;
       }
-      result = result && (hasInstanceid() == other.hasInstanceid());
+      if (hasInstanceid() != other.hasInstanceid()) return false;
       if (hasInstanceid()) {
-        result = result && getInstanceid()
-            .equals(other.getInstanceid());
+        if (!getInstanceid()
+            .equals(other.getInstanceid())) return false;
       }
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -28218,18 +28168,18 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersion buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersion result = new ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersion(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.skipchainid_ = skipchainid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.instanceid_ = instanceid_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000004;
         }
-        result.version_ = version_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -28237,35 +28187,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersion buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -28332,7 +28282,7 @@ public Builder mergeFrom(
        * required bytes skipchainid = 1;
        */
       public boolean hasSkipchainid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes skipchainid = 1;
@@ -28367,7 +28317,7 @@ public Builder clearSkipchainid() {
        * required bytes instanceid = 2;
        */
       public boolean hasInstanceid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes instanceid = 2;
@@ -28402,7 +28352,7 @@ public Builder clearInstanceid() {
        * required uint64 version = 3;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required uint64 version = 3;
@@ -28598,7 +28548,7 @@ private GetLastInstanceVersion(
      * required bytes skipchainid = 1;
      */
     public boolean hasSkipchainid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes skipchainid = 1;
@@ -28613,7 +28563,7 @@ public com.google.protobuf.ByteString getSkipchainid() {
      * required bytes instanceid = 2;
      */
     public boolean hasInstanceid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes instanceid = 2;
@@ -28644,10 +28594,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, skipchainid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, instanceid_);
       }
       unknownFields.writeTo(output);
@@ -28659,11 +28609,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, skipchainid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, instanceid_);
       }
@@ -28682,19 +28632,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.GetLastInstanceVersion other = (ch.epfl.dedis.lib.proto.ByzCoinProto.GetLastInstanceVersion) obj;
 
-      boolean result = true;
-      result = result && (hasSkipchainid() == other.hasSkipchainid());
+      if (hasSkipchainid() != other.hasSkipchainid()) return false;
       if (hasSkipchainid()) {
-        result = result && getSkipchainid()
-            .equals(other.getSkipchainid());
+        if (!getSkipchainid()
+            .equals(other.getSkipchainid())) return false;
       }
-      result = result && (hasInstanceid() == other.hasInstanceid());
+      if (hasInstanceid() != other.hasInstanceid()) return false;
       if (hasInstanceid()) {
-        result = result && getInstanceid()
-            .equals(other.getInstanceid());
+        if (!getInstanceid()
+            .equals(other.getInstanceid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -28882,11 +28831,11 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetLastInstanceVersion buildPartial(
         ch.epfl.dedis.lib.proto.ByzCoinProto.GetLastInstanceVersion result = new ch.epfl.dedis.lib.proto.ByzCoinProto.GetLastInstanceVersion(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.skipchainid_ = skipchainid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.instanceid_ = instanceid_;
@@ -28897,35 +28846,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetLastInstanceVersion buildPartial(
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -28986,7 +28935,7 @@ public Builder mergeFrom(
        * required bytes skipchainid = 1;
        */
       public boolean hasSkipchainid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes skipchainid = 1;
@@ -29021,7 +28970,7 @@ public Builder clearSkipchainid() {
        * required bytes instanceid = 2;
        */
       public boolean hasInstanceid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes instanceid = 2;
@@ -29149,7 +29098,6 @@ private GetInstanceVersionResponse(com.google.protobuf.GeneratedMessageV3.Builde
       super(builder);
     }
     private GetInstanceVersionResponse() {
-      blockindex_ = 0;
     }
 
     @java.lang.Override
@@ -29178,7 +29126,7 @@ private GetInstanceVersionResponse(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = statechange_.toBuilder();
               }
               statechange_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange.parser(), extensionRegistry);
@@ -29233,7 +29181,7 @@ private GetInstanceVersionResponse(
      * required .byzcoin.StateChange statechange = 1;
      */
     public boolean hasStatechange() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required .byzcoin.StateChange statechange = 1;
@@ -29254,7 +29202,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeOrBuilder getStatechangeO
      * required sint32 blockindex = 2;
      */
     public boolean hasBlockindex() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required sint32 blockindex = 2;
@@ -29289,10 +29237,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getStatechange());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeSInt32(2, blockindex_);
       }
       unknownFields.writeTo(output);
@@ -29304,11 +29252,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getStatechange());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(2, blockindex_);
       }
@@ -29327,19 +29275,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersionResponse other = (ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersionResponse) obj;
 
-      boolean result = true;
-      result = result && (hasStatechange() == other.hasStatechange());
+      if (hasStatechange() != other.hasStatechange()) return false;
       if (hasStatechange()) {
-        result = result && getStatechange()
-            .equals(other.getStatechange());
+        if (!getStatechange()
+            .equals(other.getStatechange())) return false;
       }
-      result = result && (hasBlockindex() == other.hasBlockindex());
+      if (hasBlockindex() != other.hasBlockindex()) return false;
       if (hasBlockindex()) {
-        result = result && (getBlockindex()
-            == other.getBlockindex());
+        if (getBlockindex()
+            != other.getBlockindex()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -29534,18 +29481,18 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersionResponse buildPart
         ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersionResponse result = new ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersionResponse(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (statechangeBuilder_ == null) {
+            result.statechange_ = statechange_;
+          } else {
+            result.statechange_ = statechangeBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (statechangeBuilder_ == null) {
-          result.statechange_ = statechange_;
-        } else {
-          result.statechange_ = statechangeBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.blockindex_ = blockindex_;
           to_bitField0_ |= 0x00000002;
         }
-        result.blockindex_ = blockindex_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -29553,35 +29500,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersionResponse buildPart
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -29640,14 +29587,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange statechange_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange statechange_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange, ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeOrBuilder> statechangeBuilder_;
       /**
        * required .byzcoin.StateChange statechange = 1;
        */
       public boolean hasStatechange() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required .byzcoin.StateChange statechange = 1;
@@ -29694,7 +29641,7 @@ public Builder setStatechange(
        */
       public Builder mergeStatechange(ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange value) {
         if (statechangeBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               statechange_ != null &&
               statechange_ != ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange.getDefaultInstance()) {
             statechange_ =
@@ -29763,7 +29710,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeOrBuilder getStatechangeO
        * required sint32 blockindex = 2;
        */
       public boolean hasBlockindex() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required sint32 blockindex = 2;
@@ -29959,7 +29906,7 @@ private GetAllInstanceVersion(
      * required bytes skipchainid = 1;
      */
     public boolean hasSkipchainid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes skipchainid = 1;
@@ -29974,7 +29921,7 @@ public com.google.protobuf.ByteString getSkipchainid() {
      * required bytes instanceid = 2;
      */
     public boolean hasInstanceid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes instanceid = 2;
@@ -30005,10 +29952,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, skipchainid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, instanceid_);
       }
       unknownFields.writeTo(output);
@@ -30020,11 +29967,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, skipchainid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, instanceid_);
       }
@@ -30043,19 +29990,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersion other = (ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersion) obj;
 
-      boolean result = true;
-      result = result && (hasSkipchainid() == other.hasSkipchainid());
+      if (hasSkipchainid() != other.hasSkipchainid()) return false;
       if (hasSkipchainid()) {
-        result = result && getSkipchainid()
-            .equals(other.getSkipchainid());
+        if (!getSkipchainid()
+            .equals(other.getSkipchainid())) return false;
       }
-      result = result && (hasInstanceid() == other.hasInstanceid());
+      if (hasInstanceid() != other.hasInstanceid()) return false;
       if (hasInstanceid()) {
-        result = result && getInstanceid()
-            .equals(other.getInstanceid());
+        if (!getInstanceid()
+            .equals(other.getInstanceid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -30243,11 +30189,11 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersion buildPartial()
         ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersion result = new ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersion(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.skipchainid_ = skipchainid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.instanceid_ = instanceid_;
@@ -30258,35 +30204,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersion buildPartial()
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -30347,7 +30293,7 @@ public Builder mergeFrom(
        * required bytes skipchainid = 1;
        */
       public boolean hasSkipchainid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes skipchainid = 1;
@@ -30382,7 +30328,7 @@ public Builder clearSkipchainid() {
        * required bytes instanceid = 2;
        */
       public boolean hasInstanceid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes instanceid = 2;
@@ -30538,7 +30484,7 @@ private GetAllInstanceVersionResponse(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 statechanges_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -30561,7 +30507,7 @@ private GetAllInstanceVersionResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           statechanges_ = java.util.Collections.unmodifiableList(statechanges_);
         }
         this.unknownFields = unknownFields.build();
@@ -30667,11 +30613,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersionResponse other = (ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersionResponse) obj;
 
-      boolean result = true;
-      result = result && getStatechangesList()
-          .equals(other.getStatechangesList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getStatechangesList()
+          .equals(other.getStatechangesList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -30858,7 +30803,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersionResponse buildP
         ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersionResponse result = new ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersionResponse(this);
         int from_bitField0_ = bitField0_;
         if (statechangesBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             statechanges_ = java.util.Collections.unmodifiableList(statechanges_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -30872,35 +30817,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetAllInstanceVersionResponse buildP
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -30978,7 +30923,7 @@ public Builder mergeFrom(
       private java.util.List statechanges_ =
         java.util.Collections.emptyList();
       private void ensureStatechangesIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           statechanges_ = new java.util.ArrayList(statechanges_);
           bitField0_ |= 0x00000001;
          }
@@ -31207,7 +31152,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersionResponse.Builder a
           statechangesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersionResponse, ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersionResponse.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.GetInstanceVersionResponseOrBuilder>(
                   statechanges_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           statechanges_ = null;
@@ -31319,7 +31264,6 @@ private CheckStateChangeValidity(com.google.protobuf.GeneratedMessageV3.Builder<
     private CheckStateChangeValidity() {
       skipchainid_ = com.google.protobuf.ByteString.EMPTY;
       instanceid_ = com.google.protobuf.ByteString.EMPTY;
-      version_ = 0L;
     }
 
     @java.lang.Override
@@ -31400,7 +31344,7 @@ private CheckStateChangeValidity(
      * required bytes skipchainid = 1;
      */
     public boolean hasSkipchainid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes skipchainid = 1;
@@ -31415,7 +31359,7 @@ public com.google.protobuf.ByteString getSkipchainid() {
      * required bytes instanceid = 2;
      */
     public boolean hasInstanceid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes instanceid = 2;
@@ -31430,7 +31374,7 @@ public com.google.protobuf.ByteString getInstanceid() {
      * required uint64 version = 3;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required uint64 version = 3;
@@ -31465,13 +31409,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, skipchainid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, instanceid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeUInt64(3, version_);
       }
       unknownFields.writeTo(output);
@@ -31483,15 +31427,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, skipchainid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, instanceid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(3, version_);
       }
@@ -31510,24 +31454,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.CheckStateChangeValidity other = (ch.epfl.dedis.lib.proto.ByzCoinProto.CheckStateChangeValidity) obj;
 
-      boolean result = true;
-      result = result && (hasSkipchainid() == other.hasSkipchainid());
+      if (hasSkipchainid() != other.hasSkipchainid()) return false;
       if (hasSkipchainid()) {
-        result = result && getSkipchainid()
-            .equals(other.getSkipchainid());
+        if (!getSkipchainid()
+            .equals(other.getSkipchainid())) return false;
       }
-      result = result && (hasInstanceid() == other.hasInstanceid());
+      if (hasInstanceid() != other.hasInstanceid()) return false;
       if (hasInstanceid()) {
-        result = result && getInstanceid()
-            .equals(other.getInstanceid());
+        if (!getInstanceid()
+            .equals(other.getInstanceid())) return false;
       }
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -31723,18 +31666,18 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CheckStateChangeValidity buildPartia
         ch.epfl.dedis.lib.proto.ByzCoinProto.CheckStateChangeValidity result = new ch.epfl.dedis.lib.proto.ByzCoinProto.CheckStateChangeValidity(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.skipchainid_ = skipchainid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.instanceid_ = instanceid_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000004;
         }
-        result.version_ = version_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -31742,35 +31685,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CheckStateChangeValidity buildPartia
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -31837,7 +31780,7 @@ public Builder mergeFrom(
        * required bytes skipchainid = 1;
        */
       public boolean hasSkipchainid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes skipchainid = 1;
@@ -31872,7 +31815,7 @@ public Builder clearSkipchainid() {
        * required bytes instanceid = 2;
        */
       public boolean hasInstanceid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes instanceid = 2;
@@ -31907,7 +31850,7 @@ public Builder clearInstanceid() {
        * required uint64 version = 3;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required uint64 version = 3;
@@ -32071,7 +32014,7 @@ private CheckStateChangeValidityResponse(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 statechanges_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -32099,7 +32042,7 @@ private CheckStateChangeValidityResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           statechanges_ = java.util.Collections.unmodifiableList(statechanges_);
         }
         this.unknownFields = unknownFields.build();
@@ -32161,7 +32104,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeOrBuilder getStatechanges
      * required bytes blockid = 2;
      */
     public boolean hasBlockid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes blockid = 2;
@@ -32197,7 +32140,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
       for (int i = 0; i < statechanges_.size(); i++) {
         output.writeMessage(1, statechanges_.get(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(2, blockid_);
       }
       unknownFields.writeTo(output);
@@ -32213,7 +32156,7 @@ public int getSerializedSize() {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, statechanges_.get(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, blockid_);
       }
@@ -32232,16 +32175,15 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.CheckStateChangeValidityResponse other = (ch.epfl.dedis.lib.proto.ByzCoinProto.CheckStateChangeValidityResponse) obj;
 
-      boolean result = true;
-      result = result && getStatechangesList()
-          .equals(other.getStatechangesList());
-      result = result && (hasBlockid() == other.hasBlockid());
+      if (!getStatechangesList()
+          .equals(other.getStatechangesList())) return false;
+      if (hasBlockid() != other.hasBlockid()) return false;
       if (hasBlockid()) {
-        result = result && getBlockid()
-            .equals(other.getBlockid());
+        if (!getBlockid()
+            .equals(other.getBlockid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -32436,7 +32378,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CheckStateChangeValidityResponse bui
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
         if (statechangesBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             statechanges_ = java.util.Collections.unmodifiableList(statechanges_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -32444,7 +32386,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CheckStateChangeValidityResponse bui
         } else {
           result.statechanges_ = statechangesBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.blockid_ = blockid_;
@@ -32455,35 +32397,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CheckStateChangeValidityResponse bui
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -32567,7 +32509,7 @@ public Builder mergeFrom(
       private java.util.List statechanges_ =
         java.util.Collections.emptyList();
       private void ensureStatechangesIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           statechanges_ = new java.util.ArrayList(statechanges_);
           bitField0_ |= 0x00000001;
          }
@@ -32796,7 +32738,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange.Builder addStatechangesB
           statechangesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange, ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeOrBuilder>(
                   statechanges_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           statechanges_ = null;
@@ -32809,7 +32751,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.StateChange.Builder addStatechangesB
        * required bytes blockid = 2;
        */
       public boolean hasBlockid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes blockid = 2;
@@ -32993,7 +32935,7 @@ private DebugRequest(
      * optional bytes byzcoinid = 1;
      */
     public boolean hasByzcoinid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * optional bytes byzcoinid = 1;
@@ -33016,7 +32958,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, byzcoinid_);
       }
       unknownFields.writeTo(output);
@@ -33028,7 +32970,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, byzcoinid_);
       }
@@ -33047,14 +32989,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRequest other = (ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRequest) obj;
 
-      boolean result = true;
-      result = result && (hasByzcoinid() == other.hasByzcoinid());
+      if (hasByzcoinid() != other.hasByzcoinid()) return false;
       if (hasByzcoinid()) {
-        result = result && getByzcoinid()
-            .equals(other.getByzcoinid());
+        if (!getByzcoinid()
+            .equals(other.getByzcoinid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -33236,7 +33177,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRequest buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRequest result = new ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRequest(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.byzcoinid_ = byzcoinid_;
@@ -33247,35 +33188,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRequest buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -33327,7 +33268,7 @@ public Builder mergeFrom(
        * optional bytes byzcoinid = 1;
        */
       public boolean hasByzcoinid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * optional bytes byzcoinid = 1;
@@ -33509,7 +33450,7 @@ private DebugResponse(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 byzcoins_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -33518,7 +33459,7 @@ private DebugResponse(
               break;
             }
             case 18: {
-              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
                 dump_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000002;
               }
@@ -33541,10 +33482,10 @@ private DebugResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           byzcoins_ = java.util.Collections.unmodifiableList(byzcoins_);
         }
-        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
           dump_ = java.util.Collections.unmodifiableList(dump_);
         }
         this.unknownFields = unknownFields.build();
@@ -33698,13 +33639,12 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponse other = (ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponse) obj;
 
-      boolean result = true;
-      result = result && getByzcoinsList()
-          .equals(other.getByzcoinsList());
-      result = result && getDumpList()
-          .equals(other.getDumpList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getByzcoinsList()
+          .equals(other.getByzcoinsList())) return false;
+      if (!getDumpList()
+          .equals(other.getDumpList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -33903,7 +33843,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponse buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponse result = new ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponse(this);
         int from_bitField0_ = bitField0_;
         if (byzcoinsBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             byzcoins_ = java.util.Collections.unmodifiableList(byzcoins_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -33912,7 +33852,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponse buildPartial() {
           result.byzcoins_ = byzcoinsBuilder_.build();
         }
         if (dumpBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          if (((bitField0_ & 0x00000002) != 0)) {
             dump_ = java.util.Collections.unmodifiableList(dump_);
             bitField0_ = (bitField0_ & ~0x00000002);
           }
@@ -33926,35 +33866,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponse buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -34063,7 +34003,7 @@ public Builder mergeFrom(
       private java.util.List byzcoins_ =
         java.util.Collections.emptyList();
       private void ensureByzcoinsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           byzcoins_ = new java.util.ArrayList(byzcoins_);
           bitField0_ |= 0x00000001;
          }
@@ -34292,7 +34232,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseByzcoin.Builder addByzc
           byzcoinsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseByzcoin, ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseByzcoin.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseByzcoinOrBuilder>(
                   byzcoins_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           byzcoins_ = null;
@@ -34303,7 +34243,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseByzcoin.Builder addByzc
       private java.util.List dump_ =
         java.util.Collections.emptyList();
       private void ensureDumpIsMutable() {
-        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+        if (!((bitField0_ & 0x00000002) != 0)) {
           dump_ = new java.util.ArrayList(dump_);
           bitField0_ |= 0x00000002;
          }
@@ -34532,7 +34472,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseState.Builder addDumpBu
           dumpBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseState, ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseState.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseStateOrBuilder>(
                   dump_,
-                  ((bitField0_ & 0x00000002) == 0x00000002),
+                  ((bitField0_ & 0x00000002) != 0),
                   getParentForChildren(),
                   isClean());
           dump_ = null;
@@ -34683,7 +34623,7 @@ private DebugResponseByzcoin(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = genesis_.toBuilder();
               }
               genesis_ = input.readMessage(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.parser(), extensionRegistry);
@@ -34696,7 +34636,7 @@ private DebugResponseByzcoin(
             }
             case 26: {
               ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (((bitField0_ & 0x00000004) != 0)) {
                 subBuilder = latest_.toBuilder();
               }
               latest_ = input.readMessage(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.parser(), extensionRegistry);
@@ -34746,7 +34686,7 @@ private DebugResponseByzcoin(
      * required bytes byzcoinid = 1;
      */
     public boolean hasByzcoinid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes byzcoinid = 1;
@@ -34761,7 +34701,7 @@ public com.google.protobuf.ByteString getByzcoinid() {
      * optional .skipchain.SkipBlock genesis = 2;
      */
     public boolean hasGenesis() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * optional .skipchain.SkipBlock genesis = 2;
@@ -34782,7 +34722,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder getGenesisOrBui
      * optional .skipchain.SkipBlock latest = 3;
      */
     public boolean hasLatest() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * optional .skipchain.SkipBlock latest = 3;
@@ -34827,13 +34767,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getGenesis());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeMessage(3, getLatest());
       }
       unknownFields.writeTo(output);
@@ -34845,15 +34785,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getGenesis());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getLatest());
       }
@@ -34872,24 +34812,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseByzcoin other = (ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseByzcoin) obj;
 
-      boolean result = true;
-      result = result && (hasByzcoinid() == other.hasByzcoinid());
+      if (hasByzcoinid() != other.hasByzcoinid()) return false;
       if (hasByzcoinid()) {
-        result = result && getByzcoinid()
-            .equals(other.getByzcoinid());
+        if (!getByzcoinid()
+            .equals(other.getByzcoinid())) return false;
       }
-      result = result && (hasGenesis() == other.hasGenesis());
+      if (hasGenesis() != other.hasGenesis()) return false;
       if (hasGenesis()) {
-        result = result && getGenesis()
-            .equals(other.getGenesis());
+        if (!getGenesis()
+            .equals(other.getGenesis())) return false;
       }
-      result = result && (hasLatest() == other.hasLatest());
+      if (hasLatest() != other.hasLatest()) return false;
       if (hasLatest()) {
-        result = result && getLatest()
-            .equals(other.getLatest());
+        if (!getLatest()
+            .equals(other.getLatest())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -35093,26 +35032,26 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseByzcoin buildPartial()
         ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseByzcoin result = new ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseByzcoin(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.byzcoinid_ = byzcoinid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (genesisBuilder_ == null) {
+            result.genesis_ = genesis_;
+          } else {
+            result.genesis_ = genesisBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (genesisBuilder_ == null) {
-          result.genesis_ = genesis_;
-        } else {
-          result.genesis_ = genesisBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          if (latestBuilder_ == null) {
+            result.latest_ = latest_;
+          } else {
+            result.latest_ = latestBuilder_.build();
+          }
           to_bitField0_ |= 0x00000004;
         }
-        if (latestBuilder_ == null) {
-          result.latest_ = latest_;
-        } else {
-          result.latest_ = latestBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -35120,35 +35059,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseByzcoin buildPartial()
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -35219,7 +35158,7 @@ public Builder mergeFrom(
        * required bytes byzcoinid = 1;
        */
       public boolean hasByzcoinid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes byzcoinid = 1;
@@ -35249,14 +35188,14 @@ public Builder clearByzcoinid() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock genesis_ = null;
+      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock genesis_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder> genesisBuilder_;
       /**
        * optional .skipchain.SkipBlock genesis = 2;
        */
       public boolean hasGenesis() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * optional .skipchain.SkipBlock genesis = 2;
@@ -35303,7 +35242,7 @@ public Builder setGenesis(
        */
       public Builder mergeGenesis(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock value) {
         if (genesisBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               genesis_ != null &&
               genesis_ != ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.getDefaultInstance()) {
             genesis_ =
@@ -35367,14 +35306,14 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder getGenesisOrBui
         return genesisBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock latest_ = null;
+      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock latest_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder> latestBuilder_;
       /**
        * optional .skipchain.SkipBlock latest = 3;
        */
       public boolean hasLatest() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * optional .skipchain.SkipBlock latest = 3;
@@ -35421,7 +35360,7 @@ public Builder setLatest(
        */
       public Builder mergeLatest(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock value) {
         if (latestBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+          if (((bitField0_ & 0x00000004) != 0) &&
               latest_ != null &&
               latest_ != ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.getDefaultInstance()) {
             latest_ =
@@ -35614,7 +35553,7 @@ private DebugResponseState(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = state_.toBuilder();
               }
               state_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody.parser(), extensionRegistry);
@@ -35664,7 +35603,7 @@ private DebugResponseState(
      * required bytes key = 1;
      */
     public boolean hasKey() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes key = 1;
@@ -35679,7 +35618,7 @@ public com.google.protobuf.ByteString getKey() {
      * required .byzcoin.StateChangeBody state = 2;
      */
     public boolean hasState() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required .byzcoin.StateChangeBody state = 2;
@@ -35720,10 +35659,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, key_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getState());
       }
       unknownFields.writeTo(output);
@@ -35735,11 +35674,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, key_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getState());
       }
@@ -35758,19 +35697,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseState other = (ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseState) obj;
 
-      boolean result = true;
-      result = result && (hasKey() == other.hasKey());
+      if (hasKey() != other.hasKey()) return false;
       if (hasKey()) {
-        result = result && getKey()
-            .equals(other.getKey());
+        if (!getKey()
+            .equals(other.getKey())) return false;
       }
-      result = result && (hasState() == other.hasState());
+      if (hasState() != other.hasState()) return false;
       if (hasState()) {
-        result = result && getState()
-            .equals(other.getState());
+        if (!getState()
+            .equals(other.getState())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -35962,18 +35900,18 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseState buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseState result = new ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseState(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.key_ = key_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (stateBuilder_ == null) {
+            result.state_ = state_;
+          } else {
+            result.state_ = stateBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (stateBuilder_ == null) {
-          result.state_ = state_;
-        } else {
-          result.state_ = stateBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -35981,35 +35919,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugResponseState buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -36073,7 +36011,7 @@ public Builder mergeFrom(
        * required bytes key = 1;
        */
       public boolean hasKey() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes key = 1;
@@ -36103,14 +36041,14 @@ public Builder clearKey() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody state_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody state_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody, ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBodyOrBuilder> stateBuilder_;
       /**
        * required .byzcoin.StateChangeBody state = 2;
        */
       public boolean hasState() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required .byzcoin.StateChangeBody state = 2;
@@ -36157,7 +36095,7 @@ public Builder setState(
        */
       public Builder mergeState(ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody value) {
         if (stateBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               state_ != null &&
               state_ != ch.epfl.dedis.lib.proto.ByzCoinProto.StateChangeBody.getDefaultInstance()) {
             state_ =
@@ -36390,7 +36328,7 @@ private DebugRemoveRequest(
      * required bytes byzcoinid = 1;
      */
     public boolean hasByzcoinid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes byzcoinid = 1;
@@ -36405,7 +36343,7 @@ public com.google.protobuf.ByteString getByzcoinid() {
      * required bytes signature = 2;
      */
     public boolean hasSignature() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes signature = 2;
@@ -36436,10 +36374,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, signature_);
       }
       unknownFields.writeTo(output);
@@ -36451,11 +36389,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, signature_);
       }
@@ -36474,19 +36412,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRemoveRequest other = (ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRemoveRequest) obj;
 
-      boolean result = true;
-      result = result && (hasByzcoinid() == other.hasByzcoinid());
+      if (hasByzcoinid() != other.hasByzcoinid()) return false;
       if (hasByzcoinid()) {
-        result = result && getByzcoinid()
-            .equals(other.getByzcoinid());
+        if (!getByzcoinid()
+            .equals(other.getByzcoinid())) return false;
       }
-      result = result && (hasSignature() == other.hasSignature());
+      if (hasSignature() != other.hasSignature()) return false;
       if (hasSignature()) {
-        result = result && getSignature()
-            .equals(other.getSignature());
+        if (!getSignature()
+            .equals(other.getSignature())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -36674,11 +36611,11 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRemoveRequest buildPartial() {
         ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRemoveRequest result = new ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRemoveRequest(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.byzcoinid_ = byzcoinid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.signature_ = signature_;
@@ -36689,35 +36626,35 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.DebugRemoveRequest buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -36778,7 +36715,7 @@ public Builder mergeFrom(
        * required bytes byzcoinid = 1;
        */
       public boolean hasByzcoinid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes byzcoinid = 1;
@@ -36813,7 +36750,7 @@ public Builder clearByzcoinid() {
        * required bytes signature = 2;
        */
       public boolean hasSignature() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes signature = 2;
diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java
index fa952c1c96..4cd489c030 100644
--- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java
+++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java
@@ -302,7 +302,7 @@ private Write(
      * required bytes data = 1;
      */
     public boolean hasData() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -326,7 +326,7 @@ public com.google.protobuf.ByteString getData() {
      * required bytes u = 2;
      */
     public boolean hasU() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -352,7 +352,7 @@ public com.google.protobuf.ByteString getU() {
      * required bytes ubar = 3;
      */
     public boolean hasUbar() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -378,7 +378,7 @@ public com.google.protobuf.ByteString getUbar() {
      * required bytes e = 4;
      */
     public boolean hasE() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * 
@@ -402,7 +402,7 @@ public com.google.protobuf.ByteString getE() {
      * required bytes f = 5;
      */
     public boolean hasF() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * 
@@ -427,7 +427,7 @@ public com.google.protobuf.ByteString getF() {
      * required bytes c = 6;
      */
     public boolean hasC() {
-      return ((bitField0_ & 0x00000020) == 0x00000020);
+      return ((bitField0_ & 0x00000020) != 0);
     }
     /**
      * 
@@ -451,7 +451,7 @@ public com.google.protobuf.ByteString getC() {
      * optional bytes extradata = 7;
      */
     public boolean hasExtradata() {
-      return ((bitField0_ & 0x00000040) == 0x00000040);
+      return ((bitField0_ & 0x00000040) != 0);
     }
     /**
      * 
@@ -474,7 +474,7 @@ public com.google.protobuf.ByteString getExtradata() {
      * required bytes ltsid = 8;
      */
     public boolean hasLtsid() {
-      return ((bitField0_ & 0x00000080) == 0x00000080);
+      return ((bitField0_ & 0x00000080) != 0);
     }
     /**
      * 
@@ -529,28 +529,28 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, data_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, u_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, ubar_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeBytes(4, e_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         output.writeBytes(5, f_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         output.writeBytes(6, c_);
       }
-      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+      if (((bitField0_ & 0x00000040) != 0)) {
         output.writeBytes(7, extradata_);
       }
-      if (((bitField0_ & 0x00000080) == 0x00000080)) {
+      if (((bitField0_ & 0x00000080) != 0)) {
         output.writeBytes(8, ltsid_);
       }
       unknownFields.writeTo(output);
@@ -562,35 +562,35 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, data_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, u_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, ubar_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(4, e_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(5, f_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(6, c_);
       }
-      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+      if (((bitField0_ & 0x00000040) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(7, extradata_);
       }
-      if (((bitField0_ & 0x00000080) == 0x00000080)) {
+      if (((bitField0_ & 0x00000080) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(8, ltsid_);
       }
@@ -609,49 +609,48 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.Write other = (ch.epfl.dedis.lib.proto.Calypso.Write) obj;
 
-      boolean result = true;
-      result = result && (hasData() == other.hasData());
+      if (hasData() != other.hasData()) return false;
       if (hasData()) {
-        result = result && getData()
-            .equals(other.getData());
+        if (!getData()
+            .equals(other.getData())) return false;
       }
-      result = result && (hasU() == other.hasU());
+      if (hasU() != other.hasU()) return false;
       if (hasU()) {
-        result = result && getU()
-            .equals(other.getU());
+        if (!getU()
+            .equals(other.getU())) return false;
       }
-      result = result && (hasUbar() == other.hasUbar());
+      if (hasUbar() != other.hasUbar()) return false;
       if (hasUbar()) {
-        result = result && getUbar()
-            .equals(other.getUbar());
+        if (!getUbar()
+            .equals(other.getUbar())) return false;
       }
-      result = result && (hasE() == other.hasE());
+      if (hasE() != other.hasE()) return false;
       if (hasE()) {
-        result = result && getE()
-            .equals(other.getE());
+        if (!getE()
+            .equals(other.getE())) return false;
       }
-      result = result && (hasF() == other.hasF());
+      if (hasF() != other.hasF()) return false;
       if (hasF()) {
-        result = result && getF()
-            .equals(other.getF());
+        if (!getF()
+            .equals(other.getF())) return false;
       }
-      result = result && (hasC() == other.hasC());
+      if (hasC() != other.hasC()) return false;
       if (hasC()) {
-        result = result && getC()
-            .equals(other.getC());
+        if (!getC()
+            .equals(other.getC())) return false;
       }
-      result = result && (hasExtradata() == other.hasExtradata());
+      if (hasExtradata() != other.hasExtradata()) return false;
       if (hasExtradata()) {
-        result = result && getExtradata()
-            .equals(other.getExtradata());
+        if (!getExtradata()
+            .equals(other.getExtradata())) return false;
       }
-      result = result && (hasLtsid() == other.hasLtsid());
+      if (hasLtsid() != other.hasLtsid()) return false;
       if (hasLtsid()) {
-        result = result && getLtsid()
-            .equals(other.getLtsid());
+        if (!getLtsid()
+            .equals(other.getLtsid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -875,35 +874,35 @@ public ch.epfl.dedis.lib.proto.Calypso.Write buildPartial() {
         ch.epfl.dedis.lib.proto.Calypso.Write result = new ch.epfl.dedis.lib.proto.Calypso.Write(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.data_ = data_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.u_ = u_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.ubar_ = ubar_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
           to_bitField0_ |= 0x00000008;
         }
         result.e_ = e_;
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((from_bitField0_ & 0x00000010) != 0)) {
           to_bitField0_ |= 0x00000010;
         }
         result.f_ = f_;
-        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+        if (((from_bitField0_ & 0x00000020) != 0)) {
           to_bitField0_ |= 0x00000020;
         }
         result.c_ = c_;
-        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
+        if (((from_bitField0_ & 0x00000040) != 0)) {
           to_bitField0_ |= 0x00000040;
         }
         result.extradata_ = extradata_;
-        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
+        if (((from_bitField0_ & 0x00000080) != 0)) {
           to_bitField0_ |= 0x00000080;
         }
         result.ltsid_ = ltsid_;
@@ -914,35 +913,35 @@ public ch.epfl.dedis.lib.proto.Calypso.Write buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -1041,7 +1040,7 @@ public Builder mergeFrom(
        * required bytes data = 1;
        */
       public boolean hasData() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -1095,7 +1094,7 @@ public Builder clearData() {
        * required bytes u = 2;
        */
       public boolean hasU() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -1149,7 +1148,7 @@ public Builder clearU() {
        * required bytes ubar = 3;
        */
       public boolean hasUbar() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -1209,7 +1208,7 @@ public Builder clearUbar() {
        * required bytes e = 4;
        */
       public boolean hasE() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * 
@@ -1261,7 +1260,7 @@ public Builder clearE() {
        * required bytes f = 5;
        */
       public boolean hasF() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return ((bitField0_ & 0x00000010) != 0);
       }
       /**
        * 
@@ -1316,7 +1315,7 @@ public Builder clearF() {
        * required bytes c = 6;
        */
       public boolean hasC() {
-        return ((bitField0_ & 0x00000020) == 0x00000020);
+        return ((bitField0_ & 0x00000020) != 0);
       }
       /**
        * 
@@ -1370,7 +1369,7 @@ public Builder clearC() {
        * optional bytes extradata = 7;
        */
       public boolean hasExtradata() {
-        return ((bitField0_ & 0x00000040) == 0x00000040);
+        return ((bitField0_ & 0x00000040) != 0);
       }
       /**
        * 
@@ -1421,7 +1420,7 @@ public Builder clearExtradata() {
        * required bytes ltsid = 8;
        */
       public boolean hasLtsid() {
-        return ((bitField0_ & 0x00000080) == 0x00000080);
+        return ((bitField0_ & 0x00000080) != 0);
       }
       /**
        * 
@@ -1632,7 +1631,7 @@ private Read(
      * required bytes write = 1;
      */
     public boolean hasWrite() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes write = 1;
@@ -1647,7 +1646,7 @@ public com.google.protobuf.ByteString getWrite() {
      * required bytes xc = 2;
      */
     public boolean hasXc() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes xc = 2;
@@ -1678,10 +1677,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, write_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, xc_);
       }
       unknownFields.writeTo(output);
@@ -1693,11 +1692,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, write_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, xc_);
       }
@@ -1716,19 +1715,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.Read other = (ch.epfl.dedis.lib.proto.Calypso.Read) obj;
 
-      boolean result = true;
-      result = result && (hasWrite() == other.hasWrite());
+      if (hasWrite() != other.hasWrite()) return false;
       if (hasWrite()) {
-        result = result && getWrite()
-            .equals(other.getWrite());
+        if (!getWrite()
+            .equals(other.getWrite())) return false;
       }
-      result = result && (hasXc() == other.hasXc());
+      if (hasXc() != other.hasXc()) return false;
       if (hasXc()) {
-        result = result && getXc()
-            .equals(other.getXc());
+        if (!getXc()
+            .equals(other.getXc())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -1916,11 +1914,11 @@ public ch.epfl.dedis.lib.proto.Calypso.Read buildPartial() {
         ch.epfl.dedis.lib.proto.Calypso.Read result = new ch.epfl.dedis.lib.proto.Calypso.Read(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.write_ = write_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.xc_ = xc_;
@@ -1931,35 +1929,35 @@ public ch.epfl.dedis.lib.proto.Calypso.Read buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -2020,7 +2018,7 @@ public Builder mergeFrom(
        * required bytes write = 1;
        */
       public boolean hasWrite() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes write = 1;
@@ -2055,7 +2053,7 @@ public Builder clearWrite() {
        * required bytes xc = 2;
        */
       public boolean hasXc() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes xc = 2;
@@ -2239,7 +2237,7 @@ private Authorise(
      * required bytes byzcoinid = 1;
      */
     public boolean hasByzcoinid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes byzcoinid = 1;
@@ -2266,7 +2264,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, byzcoinid_);
       }
       unknownFields.writeTo(output);
@@ -2278,7 +2276,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, byzcoinid_);
       }
@@ -2297,14 +2295,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.Authorise other = (ch.epfl.dedis.lib.proto.Calypso.Authorise) obj;
 
-      boolean result = true;
-      result = result && (hasByzcoinid() == other.hasByzcoinid());
+      if (hasByzcoinid() != other.hasByzcoinid()) return false;
       if (hasByzcoinid()) {
-        result = result && getByzcoinid()
-            .equals(other.getByzcoinid());
+        if (!getByzcoinid()
+            .equals(other.getByzcoinid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -2486,7 +2483,7 @@ public ch.epfl.dedis.lib.proto.Calypso.Authorise buildPartial() {
         ch.epfl.dedis.lib.proto.Calypso.Authorise result = new ch.epfl.dedis.lib.proto.Calypso.Authorise(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.byzcoinid_ = byzcoinid_;
@@ -2497,35 +2494,35 @@ public ch.epfl.dedis.lib.proto.Calypso.Authorise buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -2580,7 +2577,7 @@ public Builder mergeFrom(
        * required bytes byzcoinid = 1;
        */
       public boolean hasByzcoinid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes byzcoinid = 1;
@@ -2778,9 +2775,8 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.AuthoriseReply other = (ch.epfl.dedis.lib.proto.Calypso.AuthoriseReply) obj;
 
-      boolean result = true;
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -2959,35 +2955,35 @@ public ch.epfl.dedis.lib.proto.Calypso.AuthoriseReply buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -3146,7 +3142,7 @@ private CreateLTS(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = proof_.toBuilder();
               }
               proof_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.parser(), extensionRegistry);
@@ -3196,7 +3192,7 @@ private CreateLTS(
      * required .byzcoin.Proof proof = 1;
      */
     public boolean hasProof() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required .byzcoin.Proof proof = 1;
@@ -3233,7 +3229,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getProof());
       }
       unknownFields.writeTo(output);
@@ -3245,7 +3241,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getProof());
       }
@@ -3264,14 +3260,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.CreateLTS other = (ch.epfl.dedis.lib.proto.Calypso.CreateLTS) obj;
 
-      boolean result = true;
-      result = result && (hasProof() == other.hasProof());
+      if (hasProof() != other.hasProof()) return false;
       if (hasProof()) {
-        result = result && getProof()
-            .equals(other.getProof());
+        if (!getProof()
+            .equals(other.getProof())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -3459,14 +3454,14 @@ public ch.epfl.dedis.lib.proto.Calypso.CreateLTS buildPartial() {
         ch.epfl.dedis.lib.proto.Calypso.CreateLTS result = new ch.epfl.dedis.lib.proto.Calypso.CreateLTS(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (proofBuilder_ == null) {
+            result.proof_ = proof_;
+          } else {
+            result.proof_ = proofBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (proofBuilder_ == null) {
-          result.proof_ = proof_;
-        } else {
-          result.proof_ = proofBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -3474,35 +3469,35 @@ public ch.epfl.dedis.lib.proto.Calypso.CreateLTS buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -3555,14 +3550,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof proof_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof proof_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> proofBuilder_;
       /**
        * required .byzcoin.Proof proof = 1;
        */
       public boolean hasProof() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required .byzcoin.Proof proof = 1;
@@ -3609,7 +3604,7 @@ public Builder setProof(
        */
       public Builder mergeProof(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) {
         if (proofBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               proof_ != null &&
               proof_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance()) {
             proof_ =
@@ -3865,7 +3860,7 @@ private CreateLTSReply(
      * required bytes byzcoinid = 1;
      */
     public boolean hasByzcoinid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes byzcoinid = 1;
@@ -3880,7 +3875,7 @@ public com.google.protobuf.ByteString getByzcoinid() {
      * required bytes instanceid = 2;
      */
     public boolean hasInstanceid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes instanceid = 2;
@@ -3899,7 +3894,7 @@ public com.google.protobuf.ByteString getInstanceid() {
      * required bytes x = 3;
      */
     public boolean hasX() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -3938,13 +3933,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, instanceid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, x_);
       }
       unknownFields.writeTo(output);
@@ -3956,15 +3951,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, instanceid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, x_);
       }
@@ -3983,24 +3978,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.CreateLTSReply other = (ch.epfl.dedis.lib.proto.Calypso.CreateLTSReply) obj;
 
-      boolean result = true;
-      result = result && (hasByzcoinid() == other.hasByzcoinid());
+      if (hasByzcoinid() != other.hasByzcoinid()) return false;
       if (hasByzcoinid()) {
-        result = result && getByzcoinid()
-            .equals(other.getByzcoinid());
+        if (!getByzcoinid()
+            .equals(other.getByzcoinid())) return false;
       }
-      result = result && (hasInstanceid() == other.hasInstanceid());
+      if (hasInstanceid() != other.hasInstanceid()) return false;
       if (hasInstanceid()) {
-        result = result && getInstanceid()
-            .equals(other.getInstanceid());
+        if (!getInstanceid()
+            .equals(other.getInstanceid())) return false;
       }
-      result = result && (hasX() == other.hasX());
+      if (hasX() != other.hasX()) return false;
       if (hasX()) {
-        result = result && getX()
-            .equals(other.getX());
+        if (!getX()
+            .equals(other.getX())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -4194,15 +4188,15 @@ public ch.epfl.dedis.lib.proto.Calypso.CreateLTSReply buildPartial() {
         ch.epfl.dedis.lib.proto.Calypso.CreateLTSReply result = new ch.epfl.dedis.lib.proto.Calypso.CreateLTSReply(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.byzcoinid_ = byzcoinid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.instanceid_ = instanceid_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.x_ = x_;
@@ -4213,35 +4207,35 @@ public ch.epfl.dedis.lib.proto.Calypso.CreateLTSReply buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -4308,7 +4302,7 @@ public Builder mergeFrom(
        * required bytes byzcoinid = 1;
        */
       public boolean hasByzcoinid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes byzcoinid = 1;
@@ -4343,7 +4337,7 @@ public Builder clearByzcoinid() {
        * required bytes instanceid = 2;
        */
       public boolean hasInstanceid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes instanceid = 2;
@@ -4382,7 +4376,7 @@ public Builder clearInstanceid() {
        * required bytes x = 3;
        */
       public boolean hasX() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -4540,7 +4534,7 @@ private ReshareLTS(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = proof_.toBuilder();
               }
               proof_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.parser(), extensionRegistry);
@@ -4590,7 +4584,7 @@ private ReshareLTS(
      * required .byzcoin.Proof proof = 1;
      */
     public boolean hasProof() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required .byzcoin.Proof proof = 1;
@@ -4627,7 +4621,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getProof());
       }
       unknownFields.writeTo(output);
@@ -4639,7 +4633,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getProof());
       }
@@ -4658,14 +4652,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.ReshareLTS other = (ch.epfl.dedis.lib.proto.Calypso.ReshareLTS) obj;
 
-      boolean result = true;
-      result = result && (hasProof() == other.hasProof());
+      if (hasProof() != other.hasProof()) return false;
       if (hasProof()) {
-        result = result && getProof()
-            .equals(other.getProof());
+        if (!getProof()
+            .equals(other.getProof())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -4853,14 +4846,14 @@ public ch.epfl.dedis.lib.proto.Calypso.ReshareLTS buildPartial() {
         ch.epfl.dedis.lib.proto.Calypso.ReshareLTS result = new ch.epfl.dedis.lib.proto.Calypso.ReshareLTS(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (proofBuilder_ == null) {
+            result.proof_ = proof_;
+          } else {
+            result.proof_ = proofBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (proofBuilder_ == null) {
-          result.proof_ = proof_;
-        } else {
-          result.proof_ = proofBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -4868,35 +4861,35 @@ public ch.epfl.dedis.lib.proto.Calypso.ReshareLTS buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -4949,14 +4942,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof proof_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof proof_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> proofBuilder_;
       /**
        * required .byzcoin.Proof proof = 1;
        */
       public boolean hasProof() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required .byzcoin.Proof proof = 1;
@@ -5003,7 +4996,7 @@ public Builder setProof(
        */
       public Builder mergeProof(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) {
         if (proofBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               proof_ != null &&
               proof_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance()) {
             proof_ =
@@ -5236,9 +5229,8 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.ReshareLTSReply other = (ch.epfl.dedis.lib.proto.Calypso.ReshareLTSReply) obj;
 
-      boolean result = true;
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -5418,35 +5410,35 @@ public ch.epfl.dedis.lib.proto.Calypso.ReshareLTSReply buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -5641,7 +5633,7 @@ private DecryptKey(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = read_.toBuilder();
               }
               read_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.parser(), extensionRegistry);
@@ -5654,7 +5646,7 @@ private DecryptKey(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = write_.toBuilder();
               }
               write_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.parser(), extensionRegistry);
@@ -5708,7 +5700,7 @@ private DecryptKey(
      * required .byzcoin.Proof read = 1;
      */
     public boolean hasRead() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -5741,7 +5733,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getReadOrBuilder() {
      * required .byzcoin.Proof write = 2;
      */
     public boolean hasWrite() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -5794,10 +5786,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getRead());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getWrite());
       }
       unknownFields.writeTo(output);
@@ -5809,11 +5801,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getRead());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getWrite());
       }
@@ -5832,19 +5824,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.DecryptKey other = (ch.epfl.dedis.lib.proto.Calypso.DecryptKey) obj;
 
-      boolean result = true;
-      result = result && (hasRead() == other.hasRead());
+      if (hasRead() != other.hasRead()) return false;
       if (hasRead()) {
-        result = result && getRead()
-            .equals(other.getRead());
+        if (!getRead()
+            .equals(other.getRead())) return false;
       }
-      result = result && (hasWrite() == other.hasWrite());
+      if (hasWrite() != other.hasWrite()) return false;
       if (hasWrite()) {
-        result = result && getWrite()
-            .equals(other.getWrite());
+        if (!getWrite()
+            .equals(other.getWrite())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -6042,22 +6033,22 @@ public ch.epfl.dedis.lib.proto.Calypso.DecryptKey buildPartial() {
         ch.epfl.dedis.lib.proto.Calypso.DecryptKey result = new ch.epfl.dedis.lib.proto.Calypso.DecryptKey(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (readBuilder_ == null) {
+            result.read_ = read_;
+          } else {
+            result.read_ = readBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (readBuilder_ == null) {
-          result.read_ = read_;
-        } else {
-          result.read_ = readBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (writeBuilder_ == null) {
+            result.write_ = write_;
+          } else {
+            result.write_ = writeBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (writeBuilder_ == null) {
-          result.write_ = write_;
-        } else {
-          result.write_ = writeBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -6065,35 +6056,35 @@ public ch.epfl.dedis.lib.proto.Calypso.DecryptKey buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -6155,7 +6146,7 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof read_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof read_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> readBuilder_;
       /**
@@ -6166,7 +6157,7 @@ public Builder mergeFrom(
        * required .byzcoin.Proof read = 1;
        */
       public boolean hasRead() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -6229,7 +6220,7 @@ public Builder setRead(
        */
       public Builder mergeRead(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) {
         if (readBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               read_ != null &&
               read_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance()) {
             read_ =
@@ -6309,7 +6300,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getReadOrBuilder() {
         return readBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof write_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof write_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> writeBuilder_;
       /**
@@ -6320,7 +6311,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getReadOrBuilder() {
        * required .byzcoin.Proof write = 2;
        */
       public boolean hasWrite() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -6383,7 +6374,7 @@ public Builder setWrite(
        */
       public Builder mergeWrite(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) {
         if (writeBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               write_ != null &&
               write_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance()) {
             write_ =
@@ -6675,7 +6666,7 @@ private DecryptKeyReply(
      * required bytes c = 1;
      */
     public boolean hasC() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -6698,7 +6689,7 @@ public com.google.protobuf.ByteString getC() {
      * required bytes xhatenc = 2;
      */
     public boolean hasXhatenc() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -6721,7 +6712,7 @@ public com.google.protobuf.ByteString getXhatenc() {
      * required bytes x = 3;
      */
     public boolean hasX() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -6760,13 +6751,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, c_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, xhatenc_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, x_);
       }
       unknownFields.writeTo(output);
@@ -6778,15 +6769,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, c_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, xhatenc_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, x_);
       }
@@ -6805,24 +6796,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.DecryptKeyReply other = (ch.epfl.dedis.lib.proto.Calypso.DecryptKeyReply) obj;
 
-      boolean result = true;
-      result = result && (hasC() == other.hasC());
+      if (hasC() != other.hasC()) return false;
       if (hasC()) {
-        result = result && getC()
-            .equals(other.getC());
+        if (!getC()
+            .equals(other.getC())) return false;
       }
-      result = result && (hasXhatenc() == other.hasXhatenc());
+      if (hasXhatenc() != other.hasXhatenc()) return false;
       if (hasXhatenc()) {
-        result = result && getXhatenc()
-            .equals(other.getXhatenc());
+        if (!getXhatenc()
+            .equals(other.getXhatenc())) return false;
       }
-      result = result && (hasX() == other.hasX());
+      if (hasX() != other.hasX()) return false;
       if (hasX()) {
-        result = result && getX()
-            .equals(other.getX());
+        if (!getX()
+            .equals(other.getX())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -7016,15 +7006,15 @@ public ch.epfl.dedis.lib.proto.Calypso.DecryptKeyReply buildPartial() {
         ch.epfl.dedis.lib.proto.Calypso.DecryptKeyReply result = new ch.epfl.dedis.lib.proto.Calypso.DecryptKeyReply(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.c_ = c_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.xhatenc_ = xhatenc_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.x_ = x_;
@@ -7035,35 +7025,35 @@ public ch.epfl.dedis.lib.proto.Calypso.DecryptKeyReply buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -7134,7 +7124,7 @@ public Builder mergeFrom(
        * required bytes c = 1;
        */
       public boolean hasC() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -7185,7 +7175,7 @@ public Builder clearC() {
        * required bytes xhatenc = 2;
        */
       public boolean hasXhatenc() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -7236,7 +7226,7 @@ public Builder clearXhatenc() {
        * required bytes x = 3;
        */
       public boolean hasX() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -7443,7 +7433,7 @@ private GetLTSReply(
      * required bytes ltsid = 1;
      */
     public boolean hasLtsid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -7474,7 +7464,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, ltsid_);
       }
       unknownFields.writeTo(output);
@@ -7486,7 +7476,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, ltsid_);
       }
@@ -7505,14 +7495,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.GetLTSReply other = (ch.epfl.dedis.lib.proto.Calypso.GetLTSReply) obj;
 
-      boolean result = true;
-      result = result && (hasLtsid() == other.hasLtsid());
+      if (hasLtsid() != other.hasLtsid()) return false;
       if (hasLtsid()) {
-        result = result && getLtsid()
-            .equals(other.getLtsid());
+        if (!getLtsid()
+            .equals(other.getLtsid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -7693,7 +7682,7 @@ public ch.epfl.dedis.lib.proto.Calypso.GetLTSReply buildPartial() {
         ch.epfl.dedis.lib.proto.Calypso.GetLTSReply result = new ch.epfl.dedis.lib.proto.Calypso.GetLTSReply(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.ltsid_ = ltsid_;
@@ -7704,35 +7693,35 @@ public ch.epfl.dedis.lib.proto.Calypso.GetLTSReply buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -7791,7 +7780,7 @@ public Builder mergeFrom(
        * required bytes ltsid = 1;
        */
       public boolean hasLtsid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -7947,7 +7936,7 @@ private LtsInstanceInfo(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = roster_.toBuilder();
               }
               roster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry);
@@ -7997,7 +7986,7 @@ private LtsInstanceInfo(
      * required .onet.Roster roster = 1;
      */
     public boolean hasRoster() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required .onet.Roster roster = 1;
@@ -8034,7 +8023,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getRoster());
       }
       unknownFields.writeTo(output);
@@ -8046,7 +8035,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getRoster());
       }
@@ -8065,14 +8054,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Calypso.LtsInstanceInfo other = (ch.epfl.dedis.lib.proto.Calypso.LtsInstanceInfo) obj;
 
-      boolean result = true;
-      result = result && (hasRoster() == other.hasRoster());
+      if (hasRoster() != other.hasRoster()) return false;
       if (hasRoster()) {
-        result = result && getRoster()
-            .equals(other.getRoster());
+        if (!getRoster()
+            .equals(other.getRoster())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -8258,14 +8246,14 @@ public ch.epfl.dedis.lib.proto.Calypso.LtsInstanceInfo buildPartial() {
         ch.epfl.dedis.lib.proto.Calypso.LtsInstanceInfo result = new ch.epfl.dedis.lib.proto.Calypso.LtsInstanceInfo(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (rosterBuilder_ == null) {
+            result.roster_ = roster_;
+          } else {
+            result.roster_ = rosterBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (rosterBuilder_ == null) {
-          result.roster_ = roster_;
-        } else {
-          result.roster_ = rosterBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -8273,35 +8261,35 @@ public ch.epfl.dedis.lib.proto.Calypso.LtsInstanceInfo buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -8354,14 +8342,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_ = null;
+      private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> rosterBuilder_;
       /**
        * required .onet.Roster roster = 1;
        */
       public boolean hasRoster() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required .onet.Roster roster = 1;
@@ -8408,7 +8396,7 @@ public Builder setRoster(
        */
       public Builder mergeRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) {
         if (rosterBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               roster_ != null &&
               roster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) {
             roster_ =
@@ -8524,161 +8512,4917 @@ public ch.epfl.dedis.lib.proto.Calypso.LtsInstanceInfo getDefaultInstanceForType
 
   }
 
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_Write_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_Write_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_Read_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_Read_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_Authorise_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_Authorise_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_AuthoriseReply_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_AuthoriseReply_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_CreateLTS_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_CreateLTS_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_CreateLTSReply_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_CreateLTSReply_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_ReshareLTS_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_ReshareLTS_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_ReshareLTSReply_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_ReshareLTSReply_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_DecryptKey_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_DecryptKey_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_DecryptKeyReply_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_DecryptKeyReply_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_GetLTSReply_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_GetLTSReply_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_calypso_LtsInstanceInfo_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_calypso_LtsInstanceInfo_fieldAccessorTable;
+  public interface AuthOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:calypso.Auth)
+      com.google.protobuf.MessageOrBuilder {
 
-  public static com.google.protobuf.Descriptors.FileDescriptor
-      getDescriptor() {
-    return descriptor;
+    /**
+     * optional .calypso.AuthByzCoin byzcoin = 1;
+     */
+    boolean hasByzcoin();
+    /**
+     * optional .calypso.AuthByzCoin byzcoin = 1;
+     */
+    ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getByzcoin();
+    /**
+     * optional .calypso.AuthByzCoin byzcoin = 1;
+     */
+    ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder getByzcoinOrBuilder();
+
+    /**
+     * optional .calypso.AuthX509Cert authx509cert = 2;
+     */
+    boolean hasAuthx509Cert();
+    /**
+     * optional .calypso.AuthX509Cert authx509cert = 2;
+     */
+    ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getAuthx509Cert();
+    /**
+     * optional .calypso.AuthX509Cert authx509cert = 2;
+     */
+    ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder getAuthx509CertOrBuilder();
   }
-  private static  com.google.protobuf.Descriptors.FileDescriptor
-      descriptor;
-  static {
-    java.lang.String[] descriptorData = {
-      "\n\rcalypso.proto\022\007calypso\032\rbyzcoin.proto\032" +
-      "\nonet.proto\"q\n\005Write\022\014\n\004data\030\001 \002(\014\022\t\n\001u\030" +
-      "\002 \002(\014\022\014\n\004ubar\030\003 \002(\014\022\t\n\001e\030\004 \002(\014\022\t\n\001f\030\005 \002(" +
-      "\014\022\t\n\001c\030\006 \002(\014\022\021\n\textradata\030\007 \001(\014\022\r\n\005ltsid" +
-      "\030\010 \002(\014\"!\n\004Read\022\r\n\005write\030\001 \002(\014\022\n\n\002xc\030\002 \002(" +
-      "\014\"\036\n\tAuthorise\022\021\n\tbyzcoinid\030\001 \002(\014\"\020\n\016Aut" +
-      "horiseReply\"*\n\tCreateLTS\022\035\n\005proof\030\001 \002(\0132" +
-      "\016.byzcoin.Proof\"B\n\016CreateLTSReply\022\021\n\tbyz" +
-      "coinid\030\001 \002(\014\022\022\n\ninstanceid\030\002 \002(\014\022\t\n\001x\030\003 " +
-      "\002(\014\"+\n\nReshareLTS\022\035\n\005proof\030\001 \002(\0132\016.byzco" +
-      "in.Proof\"\021\n\017ReshareLTSReply\"I\n\nDecryptKe" +
-      "y\022\034\n\004read\030\001 \002(\0132\016.byzcoin.Proof\022\035\n\005write" +
-      "\030\002 \002(\0132\016.byzcoin.Proof\"8\n\017DecryptKeyRepl" +
-      "y\022\t\n\001c\030\001 \002(\014\022\017\n\007xhatenc\030\002 \002(\014\022\t\n\001x\030\003 \002(\014" +
-      "\"\034\n\013GetLTSReply\022\r\n\005ltsid\030\001 \002(\014\"/\n\017LtsIns" +
-      "tanceInfo\022\034\n\006roster\030\001 \002(\0132\014.onet.RosterB" +
-      "\"\n\027ch.epfl.dedis.lib.protoB\007Calypso"
-    };
-    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
-        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
-          public com.google.protobuf.ExtensionRegistry assignDescriptors(
-              com.google.protobuf.Descriptors.FileDescriptor root) {
-            descriptor = root;
-            return null;
+  /**
+   * 
+   * Auth holds all possible authentication structures. When using it to call
+   * Authorise, only one of the fields must be non-nil.
+   * 
+ * + * Protobuf type {@code calypso.Auth} + */ + public static final class Auth extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:calypso.Auth) + AuthOrBuilder { + private static final long serialVersionUID = 0L; + // Use Auth.newBuilder() to construct. + private Auth(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Auth() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Auth( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = byzcoin_.toBuilder(); + } + byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(byzcoin_); + byzcoin_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = authx509Cert_.toBuilder(); + } + authx509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(authx509Cert_); + authx509Cert_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } } - }; - com.google.protobuf.Descriptors.FileDescriptor - .internalBuildGeneratedFileFrom(descriptorData, - new com.google.protobuf.Descriptors.FileDescriptor[] { - ch.epfl.dedis.lib.proto.ByzCoinProto.getDescriptor(), - ch.epfl.dedis.lib.proto.OnetProto.getDescriptor(), - }, assigner); - internal_static_calypso_Write_descriptor = - getDescriptor().getMessageTypes().get(0); - internal_static_calypso_Write_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_Write_descriptor, - new java.lang.String[] { "Data", "U", "Ubar", "E", "F", "C", "Extradata", "Ltsid", }); - internal_static_calypso_Read_descriptor = - getDescriptor().getMessageTypes().get(1); - internal_static_calypso_Read_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_Read_descriptor, - new java.lang.String[] { "Write", "Xc", }); - internal_static_calypso_Authorise_descriptor = - getDescriptor().getMessageTypes().get(2); - internal_static_calypso_Authorise_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_Authorise_descriptor, - new java.lang.String[] { "Byzcoinid", }); - internal_static_calypso_AuthoriseReply_descriptor = - getDescriptor().getMessageTypes().get(3); - internal_static_calypso_AuthoriseReply_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_AuthoriseReply_descriptor, - new java.lang.String[] { }); - internal_static_calypso_CreateLTS_descriptor = - getDescriptor().getMessageTypes().get(4); - internal_static_calypso_CreateLTS_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_CreateLTS_descriptor, - new java.lang.String[] { "Proof", }); - internal_static_calypso_CreateLTSReply_descriptor = - getDescriptor().getMessageTypes().get(5); - internal_static_calypso_CreateLTSReply_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_CreateLTSReply_descriptor, - new java.lang.String[] { "Byzcoinid", "Instanceid", "X", }); - internal_static_calypso_ReshareLTS_descriptor = - getDescriptor().getMessageTypes().get(6); - internal_static_calypso_ReshareLTS_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_ReshareLTS_descriptor, - new java.lang.String[] { "Proof", }); - internal_static_calypso_ReshareLTSReply_descriptor = - getDescriptor().getMessageTypes().get(7); - internal_static_calypso_ReshareLTSReply_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_ReshareLTSReply_descriptor, - new java.lang.String[] { }); - internal_static_calypso_DecryptKey_descriptor = - getDescriptor().getMessageTypes().get(8); - internal_static_calypso_DecryptKey_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_DecryptKey_descriptor, - new java.lang.String[] { "Read", "Write", }); + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Auth_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Auth_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.Auth.class, ch.epfl.dedis.lib.proto.Calypso.Auth.Builder.class); + } + + private int bitField0_; + public static final int BYZCOIN_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin byzcoin_; + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getByzcoin() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance() : byzcoin_; + } + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder getByzcoinOrBuilder() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance() : byzcoin_; + } + + public static final int AUTHX509CERT_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert authx509Cert_; + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + public boolean hasAuthx509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getAuthx509Cert() { + return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance() : authx509Cert_; + } + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder getAuthx509CertOrBuilder() { + return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance() : authx509Cert_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasAuthx509Cert()) { + if (!getAuthx509Cert().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getAuthx509Cert()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getAuthx509Cert()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.Auth)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.Calypso.Auth other = (ch.epfl.dedis.lib.proto.Calypso.Auth) obj; + + if (hasByzcoin() != other.hasByzcoin()) return false; + if (hasByzcoin()) { + if (!getByzcoin() + .equals(other.getByzcoin())) return false; + } + if (hasAuthx509Cert() != other.hasAuthx509Cert()) return false; + if (hasAuthx509Cert()) { + if (!getAuthx509Cert() + .equals(other.getAuthx509Cert())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasByzcoin()) { + hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; + hash = (53 * hash) + getByzcoin().hashCode(); + } + if (hasAuthx509Cert()) { + hash = (37 * hash) + AUTHX509CERT_FIELD_NUMBER; + hash = (53 * hash) + getAuthx509Cert().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.Auth prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Auth holds all possible authentication structures. When using it to call
+     * Authorise, only one of the fields must be non-nil.
+     * 
+ * + * Protobuf type {@code calypso.Auth} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:calypso.Auth) + ch.epfl.dedis.lib.proto.Calypso.AuthOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Auth_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Auth_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.Auth.class, ch.epfl.dedis.lib.proto.Calypso.Auth.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.Calypso.Auth.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getByzcoinFieldBuilder(); + getAuthx509CertFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (authx509CertBuilder_ == null) { + authx509Cert_ = null; + } else { + authx509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Auth_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.Auth getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.Calypso.Auth.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.Auth build() { + ch.epfl.dedis.lib.proto.Calypso.Auth result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.Auth buildPartial() { + ch.epfl.dedis.lib.proto.Calypso.Auth result = new ch.epfl.dedis.lib.proto.Calypso.Auth(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + if (byzcoinBuilder_ == null) { + result.byzcoin_ = byzcoin_; + } else { + result.byzcoin_ = byzcoinBuilder_.build(); + } + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + if (authx509CertBuilder_ == null) { + result.authx509Cert_ = authx509Cert_; + } else { + result.authx509Cert_ = authx509CertBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.Calypso.Auth) { + return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.Auth)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.Auth other) { + if (other == ch.epfl.dedis.lib.proto.Calypso.Auth.getDefaultInstance()) return this; + if (other.hasByzcoin()) { + mergeByzcoin(other.getByzcoin()); + } + if (other.hasAuthx509Cert()) { + mergeAuthx509Cert(other.getAuthx509Cert()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + return false; + } + } + if (hasAuthx509Cert()) { + if (!getAuthx509Cert().isInitialized()) { + return false; + } + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.Calypso.Auth parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.Auth) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin byzcoin_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder> byzcoinBuilder_; + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getByzcoin() { + if (byzcoinBuilder_ == null) { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance() : byzcoin_; + } else { + return byzcoinBuilder_.getMessage(); + } + } + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + public Builder setByzcoin(ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin value) { + if (byzcoinBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + byzcoin_ = value; + onChanged(); + } else { + byzcoinBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + public Builder setByzcoin( + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder builderForValue) { + if (byzcoinBuilder_ == null) { + byzcoin_ = builderForValue.build(); + onChanged(); + } else { + byzcoinBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin value) { + if (byzcoinBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + byzcoin_ != null && + byzcoin_ != ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance()) { + byzcoin_ = + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); + } else { + byzcoin_ = value; + } + onChanged(); + } else { + byzcoinBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + public Builder clearByzcoin() { + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + onChanged(); + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder getByzcoinBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getByzcoinFieldBuilder().getBuilder(); + } + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder getByzcoinOrBuilder() { + if (byzcoinBuilder_ != null) { + return byzcoinBuilder_.getMessageOrBuilder(); + } else { + return byzcoin_ == null ? + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance() : byzcoin_; + } + } + /** + * optional .calypso.AuthByzCoin byzcoin = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder> + getByzcoinFieldBuilder() { + if (byzcoinBuilder_ == null) { + byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder>( + getByzcoin(), + getParentForChildren(), + isClean()); + byzcoin_ = null; + } + return byzcoinBuilder_; + } + + private ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert authx509Cert_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert, ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder> authx509CertBuilder_; + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + public boolean hasAuthx509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getAuthx509Cert() { + if (authx509CertBuilder_ == null) { + return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance() : authx509Cert_; + } else { + return authx509CertBuilder_.getMessage(); + } + } + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + public Builder setAuthx509Cert(ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert value) { + if (authx509CertBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + authx509Cert_ = value; + onChanged(); + } else { + authx509CertBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + public Builder setAuthx509Cert( + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder builderForValue) { + if (authx509CertBuilder_ == null) { + authx509Cert_ = builderForValue.build(); + onChanged(); + } else { + authx509CertBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + public Builder mergeAuthx509Cert(ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert value) { + if (authx509CertBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + authx509Cert_ != null && + authx509Cert_ != ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance()) { + authx509Cert_ = + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.newBuilder(authx509Cert_).mergeFrom(value).buildPartial(); + } else { + authx509Cert_ = value; + } + onChanged(); + } else { + authx509CertBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + public Builder clearAuthx509Cert() { + if (authx509CertBuilder_ == null) { + authx509Cert_ = null; + onChanged(); + } else { + authx509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder getAuthx509CertBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getAuthx509CertFieldBuilder().getBuilder(); + } + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder getAuthx509CertOrBuilder() { + if (authx509CertBuilder_ != null) { + return authx509CertBuilder_.getMessageOrBuilder(); + } else { + return authx509Cert_ == null ? + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance() : authx509Cert_; + } + } + /** + * optional .calypso.AuthX509Cert authx509cert = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert, ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder> + getAuthx509CertFieldBuilder() { + if (authx509CertBuilder_ == null) { + authx509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert, ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder>( + getAuthx509Cert(), + getParentForChildren(), + isClean()); + authx509Cert_ = null; + } + return authx509CertBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:calypso.Auth) + } + + // @@protoc_insertion_point(class_scope:calypso.Auth) + private static final ch.epfl.dedis.lib.proto.Calypso.Auth DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.Auth(); + } + + public static ch.epfl.dedis.lib.proto.Calypso.Auth getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Auth parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Auth(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.Auth getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AuthByzCoinOrBuilder extends + // @@protoc_insertion_point(interface_extends:calypso.AuthByzCoin) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes byzcoinid = 1; + */ + boolean hasByzcoinid(); + /** + * required bytes byzcoinid = 1; + */ + com.google.protobuf.ByteString getByzcoinid(); + + /** + * required uint64 ttl = 2; + */ + boolean hasTtl(); + /** + * required uint64 ttl = 2; + */ + long getTtl(); + } + /** + *
+   * AuthByzCoin holds the information necessary to authenticate a byzcoin request.
+   * In the ByzCoin model, all requests are valid as long as they are stored in the
+   * blockchain with the given ID.
+   * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+   * 
+ * + * Protobuf type {@code calypso.AuthByzCoin} + */ + public static final class AuthByzCoin extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:calypso.AuthByzCoin) + AuthByzCoinOrBuilder { + private static final long serialVersionUID = 0L; + // Use AuthByzCoin.newBuilder() to construct. + private AuthByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private AuthByzCoin() { + byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AuthByzCoin( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + byzcoinid_ = input.readBytes(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + ttl_ = input.readUInt64(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.class, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder.class); + } + + private int bitField0_; + public static final int BYZCOINID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString byzcoinid_; + /** + * required bytes byzcoinid = 1; + */ + public boolean hasByzcoinid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes byzcoinid = 1; + */ + public com.google.protobuf.ByteString getByzcoinid() { + return byzcoinid_; + } + + public static final int TTL_FIELD_NUMBER = 2; + private long ttl_; + /** + * required uint64 ttl = 2; + */ + public boolean hasTtl() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required uint64 ttl = 2; + */ + public long getTtl() { + return ttl_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasByzcoinid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTtl()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, byzcoinid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeUInt64(2, ttl_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, byzcoinid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(2, ttl_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin other = (ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin) obj; + + if (hasByzcoinid() != other.hasByzcoinid()) return false; + if (hasByzcoinid()) { + if (!getByzcoinid() + .equals(other.getByzcoinid())) return false; + } + if (hasTtl() != other.hasTtl()) return false; + if (hasTtl()) { + if (getTtl() + != other.getTtl()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasByzcoinid()) { + hash = (37 * hash) + BYZCOINID_FIELD_NUMBER; + hash = (53 * hash) + getByzcoinid().hashCode(); + } + if (hasTtl()) { + hash = (37 * hash) + TTL_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getTtl()); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * AuthByzCoin holds the information necessary to authenticate a byzcoin request.
+     * In the ByzCoin model, all requests are valid as long as they are stored in the
+     * blockchain with the given ID.
+     * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+     * 
+ * + * Protobuf type {@code calypso.AuthByzCoin} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:calypso.AuthByzCoin) + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.class, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + ttl_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthByzCoin_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin build() { + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin buildPartial() { + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin result = new ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.byzcoinid_ = byzcoinid_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.ttl_ = ttl_; + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin) { + return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin other) { + if (other == ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance()) return this; + if (other.hasByzcoinid()) { + setByzcoinid(other.getByzcoinid()); + } + if (other.hasTtl()) { + setTtl(other.getTtl()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasByzcoinid()) { + return false; + } + if (!hasTtl()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes byzcoinid = 1; + */ + public boolean hasByzcoinid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes byzcoinid = 1; + */ + public com.google.protobuf.ByteString getByzcoinid() { + return byzcoinid_; + } + /** + * required bytes byzcoinid = 1; + */ + public Builder setByzcoinid(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + byzcoinid_ = value; + onChanged(); + return this; + } + /** + * required bytes byzcoinid = 1; + */ + public Builder clearByzcoinid() { + bitField0_ = (bitField0_ & ~0x00000001); + byzcoinid_ = getDefaultInstance().getByzcoinid(); + onChanged(); + return this; + } + + private long ttl_ ; + /** + * required uint64 ttl = 2; + */ + public boolean hasTtl() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required uint64 ttl = 2; + */ + public long getTtl() { + return ttl_; + } + /** + * required uint64 ttl = 2; + */ + public Builder setTtl(long value) { + bitField0_ |= 0x00000002; + ttl_ = value; + onChanged(); + return this; + } + /** + * required uint64 ttl = 2; + */ + public Builder clearTtl() { + bitField0_ = (bitField0_ & ~0x00000002); + ttl_ = 0L; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:calypso.AuthByzCoin) + } + + // @@protoc_insertion_point(class_scope:calypso.AuthByzCoin) + private static final ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin(); + } + + public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public AuthByzCoin parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AuthByzCoin(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AuthX509CertOrBuilder extends + // @@protoc_insertion_point(interface_extends:calypso.AuthX509Cert) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + java.util.List getCaList(); + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + int getCaCount(); + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + com.google.protobuf.ByteString getCa(int index); + + /** + * required sint32 threshold = 2; + */ + boolean hasThreshold(); + /** + * required sint32 threshold = 2; + */ + int getThreshold(); + } + /** + *
+   * AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
+   * request. In its simplest form, it is simply the CA that will have to sign the
+   * certificates of the requesters.
+   * The Threshold indicates how many clients must have signed the request before it
+   * is accepted.
+   * 
+ * + * Protobuf type {@code calypso.AuthX509Cert} + */ + public static final class AuthX509Cert extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:calypso.AuthX509Cert) + AuthX509CertOrBuilder { + private static final long serialVersionUID = 0L; + // Use AuthX509Cert.newBuilder() to construct. + private AuthX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private AuthX509Cert() { + ca_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AuthX509Cert( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + ca_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + ca_.add(input.readBytes()); + break; + } + case 16: { + bitField0_ |= 0x00000001; + threshold_ = input.readSInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + ca_ = java.util.Collections.unmodifiableList(ca_); // C + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthX509Cert_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.class, ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder.class); + } + + private int bitField0_; + public static final int CA_FIELD_NUMBER = 1; + private java.util.List ca_; + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public java.util.List + getCaList() { + return ca_; + } + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public int getCaCount() { + return ca_.size(); + } + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public com.google.protobuf.ByteString getCa(int index) { + return ca_.get(index); + } + + public static final int THRESHOLD_FIELD_NUMBER = 2; + private int threshold_; + /** + * required sint32 threshold = 2; + */ + public boolean hasThreshold() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required sint32 threshold = 2; + */ + public int getThreshold() { + return threshold_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasThreshold()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < ca_.size(); i++) { + output.writeBytes(1, ca_.get(i)); + } + if (((bitField0_ & 0x00000001) != 0)) { + output.writeSInt32(2, threshold_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < ca_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(ca_.get(i)); + } + size += dataSize; + size += 1 * getCaList().size(); + } + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeSInt32Size(2, threshold_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert other = (ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert) obj; + + if (!getCaList() + .equals(other.getCaList())) return false; + if (hasThreshold() != other.hasThreshold()) return false; + if (hasThreshold()) { + if (getThreshold() + != other.getThreshold()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getCaCount() > 0) { + hash = (37 * hash) + CA_FIELD_NUMBER; + hash = (53 * hash) + getCaList().hashCode(); + } + if (hasThreshold()) { + hash = (37 * hash) + THRESHOLD_FIELD_NUMBER; + hash = (53 * hash) + getThreshold(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
+     * request. In its simplest form, it is simply the CA that will have to sign the
+     * certificates of the requesters.
+     * The Threshold indicates how many clients must have signed the request before it
+     * is accepted.
+     * 
+ * + * Protobuf type {@code calypso.AuthX509Cert} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:calypso.AuthX509Cert) + ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthX509Cert_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.class, ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + ca_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + threshold_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthX509Cert_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert build() { + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert buildPartial() { + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert result = new ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((bitField0_ & 0x00000001) != 0)) { + ca_ = java.util.Collections.unmodifiableList(ca_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.ca_ = ca_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.threshold_ = threshold_; + to_bitField0_ |= 0x00000001; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert) { + return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert other) { + if (other == ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance()) return this; + if (!other.ca_.isEmpty()) { + if (ca_.isEmpty()) { + ca_ = other.ca_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureCaIsMutable(); + ca_.addAll(other.ca_); + } + onChanged(); + } + if (other.hasThreshold()) { + setThreshold(other.getThreshold()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasThreshold()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.util.List ca_ = java.util.Collections.emptyList(); + private void ensureCaIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + ca_ = new java.util.ArrayList(ca_); + bitField0_ |= 0x00000001; + } + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public java.util.List + getCaList() { + return ((bitField0_ & 0x00000001) != 0) ? + java.util.Collections.unmodifiableList(ca_) : ca_; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public int getCaCount() { + return ca_.size(); + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public com.google.protobuf.ByteString getCa(int index) { + return ca_.get(index); + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder setCa( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCaIsMutable(); + ca_.set(index, value); + onChanged(); + return this; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder addCa(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCaIsMutable(); + ca_.add(value); + onChanged(); + return this; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder addAllCa( + java.lang.Iterable values) { + ensureCaIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, ca_); + onChanged(); + return this; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder clearCa() { + ca_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + + private int threshold_ ; + /** + * required sint32 threshold = 2; + */ + public boolean hasThreshold() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required sint32 threshold = 2; + */ + public int getThreshold() { + return threshold_; + } + /** + * required sint32 threshold = 2; + */ + public Builder setThreshold(int value) { + bitField0_ |= 0x00000002; + threshold_ = value; + onChanged(); + return this; + } + /** + * required sint32 threshold = 2; + */ + public Builder clearThreshold() { + bitField0_ = (bitField0_ & ~0x00000002); + threshold_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:calypso.AuthX509Cert) + } + + // @@protoc_insertion_point(class_scope:calypso.AuthX509Cert) + private static final ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert(); + } + + public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public AuthX509Cert parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AuthX509Cert(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface GrantOrBuilder extends + // @@protoc_insertion_point(interface_extends:calypso.Grant) + com.google.protobuf.MessageOrBuilder { + + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + boolean hasByzcoin(); + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getByzcoin(); + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder getByzcoinOrBuilder(); + + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + boolean hasX509Cert(); + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getX509Cert(); + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder getX509CertOrBuilder(); + } + /** + *
+   * Grant holds one of the possible grant proofs for a reencryption request. Each
+   * grant proof must hold the secret to be reencrypted, the ephemeral key, as well
+   * as the proof itself that the request is valid. For each of the authentication
+   * schemes, this proof will be different.
+   * 
+ * + * Protobuf type {@code calypso.Grant} + */ + public static final class Grant extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:calypso.Grant) + GrantOrBuilder { + private static final long serialVersionUID = 0L; + // Use Grant.newBuilder() to construct. + private Grant(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Grant() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Grant( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = byzcoin_.toBuilder(); + } + byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(byzcoin_); + byzcoin_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = x509Cert_.toBuilder(); + } + x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(x509Cert_); + x509Cert_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Grant_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Grant_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.Grant.class, ch.epfl.dedis.lib.proto.Calypso.Grant.Builder.class); + } + + private int bitField0_; + public static final int BYZCOIN_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin byzcoin_; + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getByzcoin() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance() : byzcoin_; + } + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder getByzcoinOrBuilder() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance() : byzcoin_; + } + + public static final int X509CERT_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert x509Cert_; + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getX509Cert() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance() : x509Cert_; + } + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder getX509CertOrBuilder() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance() : x509Cert_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasX509Cert()) { + if (!getX509Cert().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getX509Cert()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getX509Cert()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.Grant)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.Calypso.Grant other = (ch.epfl.dedis.lib.proto.Calypso.Grant) obj; + + if (hasByzcoin() != other.hasByzcoin()) return false; + if (hasByzcoin()) { + if (!getByzcoin() + .equals(other.getByzcoin())) return false; + } + if (hasX509Cert() != other.hasX509Cert()) return false; + if (hasX509Cert()) { + if (!getX509Cert() + .equals(other.getX509Cert())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasByzcoin()) { + hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; + hash = (53 * hash) + getByzcoin().hashCode(); + } + if (hasX509Cert()) { + hash = (37 * hash) + X509CERT_FIELD_NUMBER; + hash = (53 * hash) + getX509Cert().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.Grant prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Grant holds one of the possible grant proofs for a reencryption request. Each
+     * grant proof must hold the secret to be reencrypted, the ephemeral key, as well
+     * as the proof itself that the request is valid. For each of the authentication
+     * schemes, this proof will be different.
+     * 
+ * + * Protobuf type {@code calypso.Grant} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:calypso.Grant) + ch.epfl.dedis.lib.proto.Calypso.GrantOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Grant_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Grant_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.Grant.class, ch.epfl.dedis.lib.proto.Calypso.Grant.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.Calypso.Grant.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getByzcoinFieldBuilder(); + getX509CertFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (x509CertBuilder_ == null) { + x509Cert_ = null; + } else { + x509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Grant_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.Grant getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.Calypso.Grant.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.Grant build() { + ch.epfl.dedis.lib.proto.Calypso.Grant result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.Grant buildPartial() { + ch.epfl.dedis.lib.proto.Calypso.Grant result = new ch.epfl.dedis.lib.proto.Calypso.Grant(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + if (byzcoinBuilder_ == null) { + result.byzcoin_ = byzcoin_; + } else { + result.byzcoin_ = byzcoinBuilder_.build(); + } + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + if (x509CertBuilder_ == null) { + result.x509Cert_ = x509Cert_; + } else { + result.x509Cert_ = x509CertBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.Calypso.Grant) { + return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.Grant)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.Grant other) { + if (other == ch.epfl.dedis.lib.proto.Calypso.Grant.getDefaultInstance()) return this; + if (other.hasByzcoin()) { + mergeByzcoin(other.getByzcoin()); + } + if (other.hasX509Cert()) { + mergeX509Cert(other.getX509Cert()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + return false; + } + } + if (hasX509Cert()) { + if (!getX509Cert().isInitialized()) { + return false; + } + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.Calypso.Grant parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.Grant) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin byzcoin_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder> byzcoinBuilder_; + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getByzcoin() { + if (byzcoinBuilder_ == null) { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance() : byzcoin_; + } else { + return byzcoinBuilder_.getMessage(); + } + } + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + public Builder setByzcoin(ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin value) { + if (byzcoinBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + byzcoin_ = value; + onChanged(); + } else { + byzcoinBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + public Builder setByzcoin( + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder builderForValue) { + if (byzcoinBuilder_ == null) { + byzcoin_ = builderForValue.build(); + onChanged(); + } else { + byzcoinBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin value) { + if (byzcoinBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + byzcoin_ != null && + byzcoin_ != ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance()) { + byzcoin_ = + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); + } else { + byzcoin_ = value; + } + onChanged(); + } else { + byzcoinBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + public Builder clearByzcoin() { + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + onChanged(); + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder getByzcoinBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getByzcoinFieldBuilder().getBuilder(); + } + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder getByzcoinOrBuilder() { + if (byzcoinBuilder_ != null) { + return byzcoinBuilder_.getMessageOrBuilder(); + } else { + return byzcoin_ == null ? + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance() : byzcoin_; + } + } + /** + * optional .calypso.GrantByzCoin byzcoin = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder> + getByzcoinFieldBuilder() { + if (byzcoinBuilder_ == null) { + byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder>( + getByzcoin(), + getParentForChildren(), + isClean()); + byzcoin_ = null; + } + return byzcoinBuilder_; + } + + private ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert x509Cert_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert, ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder> x509CertBuilder_; + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getX509Cert() { + if (x509CertBuilder_ == null) { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance() : x509Cert_; + } else { + return x509CertBuilder_.getMessage(); + } + } + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + public Builder setX509Cert(ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert value) { + if (x509CertBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + x509Cert_ = value; + onChanged(); + } else { + x509CertBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + public Builder setX509Cert( + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder builderForValue) { + if (x509CertBuilder_ == null) { + x509Cert_ = builderForValue.build(); + onChanged(); + } else { + x509CertBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert value) { + if (x509CertBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + x509Cert_ != null && + x509Cert_ != ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance()) { + x509Cert_ = + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); + } else { + x509Cert_ = value; + } + onChanged(); + } else { + x509CertBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + public Builder clearX509Cert() { + if (x509CertBuilder_ == null) { + x509Cert_ = null; + onChanged(); + } else { + x509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder getX509CertBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getX509CertFieldBuilder().getBuilder(); + } + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder getX509CertOrBuilder() { + if (x509CertBuilder_ != null) { + return x509CertBuilder_.getMessageOrBuilder(); + } else { + return x509Cert_ == null ? + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance() : x509Cert_; + } + } + /** + * optional .calypso.GrantX509Cert x509cert = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert, ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder> + getX509CertFieldBuilder() { + if (x509CertBuilder_ == null) { + x509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert, ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder>( + getX509Cert(), + getParentForChildren(), + isClean()); + x509Cert_ = null; + } + return x509CertBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:calypso.Grant) + } + + // @@protoc_insertion_point(class_scope:calypso.Grant) + private static final ch.epfl.dedis.lib.proto.Calypso.Grant DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.Grant(); + } + + public static ch.epfl.dedis.lib.proto.Calypso.Grant getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Grant parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Grant(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.Grant getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface GrantByzCoinOrBuilder extends + // @@protoc_insertion_point(interface_extends:calypso.GrantByzCoin) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required .byzcoin.Proof write = 1; + */ + boolean hasWrite(); + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required .byzcoin.Proof write = 1; + */ + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getWrite(); + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required .byzcoin.Proof write = 1; + */ + ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getWriteOrBuilder(); + + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required .byzcoin.Proof read = 2; + */ + boolean hasRead(); + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required .byzcoin.Proof read = 2; + */ + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getRead(); + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required .byzcoin.Proof read = 2; + */ + ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getReadOrBuilder(); + } + /** + *
+   * GrantByzCoin holds the proof of the write instance, holding the secret itself.
+   * The proof of the read instance holds the ephemeral key. Both proofs can be
+   * verified using one of the stored ByzCoinIDs.
+   * 
+ * + * Protobuf type {@code calypso.GrantByzCoin} + */ + public static final class GrantByzCoin extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:calypso.GrantByzCoin) + GrantByzCoinOrBuilder { + private static final long serialVersionUID = 0L; + // Use GrantByzCoin.newBuilder() to construct. + private GrantByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private GrantByzCoin() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private GrantByzCoin( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = write_.toBuilder(); + } + write_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(write_); + write_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = read_.toBuilder(); + } + read_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(read_); + read_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.class, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder.class); + } + + private int bitField0_; + public static final int WRITE_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof write_; + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required .byzcoin.Proof write = 1; + */ + public boolean hasWrite() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required .byzcoin.Proof write = 1; + */ + public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getWrite() { + return write_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : write_; + } + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required .byzcoin.Proof write = 1; + */ + public ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getWriteOrBuilder() { + return write_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : write_; + } + + public static final int READ_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof read_; + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required .byzcoin.Proof read = 2; + */ + public boolean hasRead() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required .byzcoin.Proof read = 2; + */ + public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getRead() { + return read_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : read_; + } + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required .byzcoin.Proof read = 2; + */ + public ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getReadOrBuilder() { + return read_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : read_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasWrite()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasRead()) { + memoizedIsInitialized = 0; + return false; + } + if (!getWrite().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getRead().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getWrite()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getRead()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getWrite()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getRead()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin other = (ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin) obj; + + if (hasWrite() != other.hasWrite()) return false; + if (hasWrite()) { + if (!getWrite() + .equals(other.getWrite())) return false; + } + if (hasRead() != other.hasRead()) return false; + if (hasRead()) { + if (!getRead() + .equals(other.getRead())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasWrite()) { + hash = (37 * hash) + WRITE_FIELD_NUMBER; + hash = (53 * hash) + getWrite().hashCode(); + } + if (hasRead()) { + hash = (37 * hash) + READ_FIELD_NUMBER; + hash = (53 * hash) + getRead().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * GrantByzCoin holds the proof of the write instance, holding the secret itself.
+     * The proof of the read instance holds the ephemeral key. Both proofs can be
+     * verified using one of the stored ByzCoinIDs.
+     * 
+ * + * Protobuf type {@code calypso.GrantByzCoin} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:calypso.GrantByzCoin) + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.class, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getWriteFieldBuilder(); + getReadFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (writeBuilder_ == null) { + write_ = null; + } else { + writeBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (readBuilder_ == null) { + read_ = null; + } else { + readBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantByzCoin_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin build() { + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin buildPartial() { + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin result = new ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + if (writeBuilder_ == null) { + result.write_ = write_; + } else { + result.write_ = writeBuilder_.build(); + } + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + if (readBuilder_ == null) { + result.read_ = read_; + } else { + result.read_ = readBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin) { + return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin other) { + if (other == ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance()) return this; + if (other.hasWrite()) { + mergeWrite(other.getWrite()); + } + if (other.hasRead()) { + mergeRead(other.getRead()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasWrite()) { + return false; + } + if (!hasRead()) { + return false; + } + if (!getWrite().isInitialized()) { + return false; + } + if (!getRead().isInitialized()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof write_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> writeBuilder_; + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required .byzcoin.Proof write = 1; + */ + public boolean hasWrite() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required .byzcoin.Proof write = 1; + */ + public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getWrite() { + if (writeBuilder_ == null) { + return write_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : write_; + } else { + return writeBuilder_.getMessage(); + } + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required .byzcoin.Proof write = 1; + */ + public Builder setWrite(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) { + if (writeBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + write_ = value; + onChanged(); + } else { + writeBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required .byzcoin.Proof write = 1; + */ + public Builder setWrite( + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder builderForValue) { + if (writeBuilder_ == null) { + write_ = builderForValue.build(); + onChanged(); + } else { + writeBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required .byzcoin.Proof write = 1; + */ + public Builder mergeWrite(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) { + if (writeBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + write_ != null && + write_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance()) { + write_ = + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.newBuilder(write_).mergeFrom(value).buildPartial(); + } else { + write_ = value; + } + onChanged(); + } else { + writeBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required .byzcoin.Proof write = 1; + */ + public Builder clearWrite() { + if (writeBuilder_ == null) { + write_ = null; + onChanged(); + } else { + writeBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required .byzcoin.Proof write = 1; + */ + public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder getWriteBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getWriteFieldBuilder().getBuilder(); + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required .byzcoin.Proof write = 1; + */ + public ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getWriteOrBuilder() { + if (writeBuilder_ != null) { + return writeBuilder_.getMessageOrBuilder(); + } else { + return write_ == null ? + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : write_; + } + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required .byzcoin.Proof write = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> + getWriteFieldBuilder() { + if (writeBuilder_ == null) { + writeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder>( + getWrite(), + getParentForChildren(), + isClean()); + write_ = null; + } + return writeBuilder_; + } + + private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof read_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> readBuilder_; + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required .byzcoin.Proof read = 2; + */ + public boolean hasRead() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required .byzcoin.Proof read = 2; + */ + public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getRead() { + if (readBuilder_ == null) { + return read_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : read_; + } else { + return readBuilder_.getMessage(); + } + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required .byzcoin.Proof read = 2; + */ + public Builder setRead(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) { + if (readBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + read_ = value; + onChanged(); + } else { + readBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required .byzcoin.Proof read = 2; + */ + public Builder setRead( + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder builderForValue) { + if (readBuilder_ == null) { + read_ = builderForValue.build(); + onChanged(); + } else { + readBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required .byzcoin.Proof read = 2; + */ + public Builder mergeRead(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) { + if (readBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + read_ != null && + read_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance()) { + read_ = + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.newBuilder(read_).mergeFrom(value).buildPartial(); + } else { + read_ = value; + } + onChanged(); + } else { + readBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required .byzcoin.Proof read = 2; + */ + public Builder clearRead() { + if (readBuilder_ == null) { + read_ = null; + onChanged(); + } else { + readBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required .byzcoin.Proof read = 2; + */ + public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder getReadBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getReadFieldBuilder().getBuilder(); + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required .byzcoin.Proof read = 2; + */ + public ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getReadOrBuilder() { + if (readBuilder_ != null) { + return readBuilder_.getMessageOrBuilder(); + } else { + return read_ == null ? + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : read_; + } + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required .byzcoin.Proof read = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> + getReadFieldBuilder() { + if (readBuilder_ == null) { + readBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder>( + getRead(), + getParentForChildren(), + isClean()); + read_ = null; + } + return readBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:calypso.GrantByzCoin) + } + + // @@protoc_insertion_point(class_scope:calypso.GrantByzCoin) + private static final ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin(); + } + + public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public GrantByzCoin parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new GrantByzCoin(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface GrantX509CertOrBuilder extends + // @@protoc_insertion_point(interface_extends:calypso.GrantX509Cert) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes secret = 1; + */ + boolean hasSecret(); + /** + * required bytes secret = 1; + */ + com.google.protobuf.ByteString getSecret(); + + /** + * repeated bytes certificates = 2; + */ + java.util.List getCertificatesList(); + /** + * repeated bytes certificates = 2; + */ + int getCertificatesCount(); + /** + * repeated bytes certificates = 2; + */ + com.google.protobuf.ByteString getCertificates(int index); + } + /** + *
+   * GrantX509Cert holds the proof that at least a threshold number of clients
+   * accepted the reencryption.
+   * For each client, there must exist a certificate that can be verified by the
+   * CA certificate from AuthX509Cert. Additionally, each client must sign the
+   * following message:
+   *   sha256( Secret | Ephemeral | Time )
+   * 
+ * + * Protobuf type {@code calypso.GrantX509Cert} + */ + public static final class GrantX509Cert extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:calypso.GrantX509Cert) + GrantX509CertOrBuilder { + private static final long serialVersionUID = 0L; + // Use GrantX509Cert.newBuilder() to construct. + private GrantX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private GrantX509Cert() { + secret_ = com.google.protobuf.ByteString.EMPTY; + certificates_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private GrantX509Cert( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + secret_ = input.readBytes(); + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) != 0)) { + certificates_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + certificates_.add(input.readBytes()); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); // C + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantX509Cert_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.class, ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder.class); + } + + private int bitField0_; + public static final int SECRET_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString secret_; + /** + * required bytes secret = 1; + */ + public boolean hasSecret() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes secret = 1; + */ + public com.google.protobuf.ByteString getSecret() { + return secret_; + } + + public static final int CERTIFICATES_FIELD_NUMBER = 2; + private java.util.List certificates_; + /** + * repeated bytes certificates = 2; + */ + public java.util.List + getCertificatesList() { + return certificates_; + } + /** + * repeated bytes certificates = 2; + */ + public int getCertificatesCount() { + return certificates_.size(); + } + /** + * repeated bytes certificates = 2; + */ + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasSecret()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, secret_); + } + for (int i = 0; i < certificates_.size(); i++) { + output.writeBytes(2, certificates_.get(i)); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, secret_); + } + { + int dataSize = 0; + for (int i = 0; i < certificates_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(certificates_.get(i)); + } + size += dataSize; + size += 1 * getCertificatesList().size(); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert other = (ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert) obj; + + if (hasSecret() != other.hasSecret()) return false; + if (hasSecret()) { + if (!getSecret() + .equals(other.getSecret())) return false; + } + if (!getCertificatesList() + .equals(other.getCertificatesList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasSecret()) { + hash = (37 * hash) + SECRET_FIELD_NUMBER; + hash = (53 * hash) + getSecret().hashCode(); + } + if (getCertificatesCount() > 0) { + hash = (37 * hash) + CERTIFICATES_FIELD_NUMBER; + hash = (53 * hash) + getCertificatesList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * GrantX509Cert holds the proof that at least a threshold number of clients
+     * accepted the reencryption.
+     * For each client, there must exist a certificate that can be verified by the
+     * CA certificate from AuthX509Cert. Additionally, each client must sign the
+     * following message:
+     *   sha256( Secret | Ephemeral | Time )
+     * 
+ * + * Protobuf type {@code calypso.GrantX509Cert} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:calypso.GrantX509Cert) + ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantX509Cert_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.class, ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + secret_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + certificates_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantX509Cert_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert build() { + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert buildPartial() { + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert result = new ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.secret_ = secret_; + if (((bitField0_ & 0x00000002) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.certificates_ = certificates_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert) { + return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert other) { + if (other == ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance()) return this; + if (other.hasSecret()) { + setSecret(other.getSecret()); + } + if (!other.certificates_.isEmpty()) { + if (certificates_.isEmpty()) { + certificates_ = other.certificates_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureCertificatesIsMutable(); + certificates_.addAll(other.certificates_); + } + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasSecret()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString secret_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes secret = 1; + */ + public boolean hasSecret() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes secret = 1; + */ + public com.google.protobuf.ByteString getSecret() { + return secret_; + } + /** + * required bytes secret = 1; + */ + public Builder setSecret(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + secret_ = value; + onChanged(); + return this; + } + /** + * required bytes secret = 1; + */ + public Builder clearSecret() { + bitField0_ = (bitField0_ & ~0x00000001); + secret_ = getDefaultInstance().getSecret(); + onChanged(); + return this; + } + + private java.util.List certificates_ = java.util.Collections.emptyList(); + private void ensureCertificatesIsMutable() { + if (!((bitField0_ & 0x00000002) != 0)) { + certificates_ = new java.util.ArrayList(certificates_); + bitField0_ |= 0x00000002; + } + } + /** + * repeated bytes certificates = 2; + */ + public java.util.List + getCertificatesList() { + return ((bitField0_ & 0x00000002) != 0) ? + java.util.Collections.unmodifiableList(certificates_) : certificates_; + } + /** + * repeated bytes certificates = 2; + */ + public int getCertificatesCount() { + return certificates_.size(); + } + /** + * repeated bytes certificates = 2; + */ + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); + } + /** + * repeated bytes certificates = 2; + */ + public Builder setCertificates( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCertificatesIsMutable(); + certificates_.set(index, value); + onChanged(); + return this; + } + /** + * repeated bytes certificates = 2; + */ + public Builder addCertificates(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCertificatesIsMutable(); + certificates_.add(value); + onChanged(); + return this; + } + /** + * repeated bytes certificates = 2; + */ + public Builder addAllCertificates( + java.lang.Iterable values) { + ensureCertificatesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, certificates_); + onChanged(); + return this; + } + /** + * repeated bytes certificates = 2; + */ + public Builder clearCertificates() { + certificates_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:calypso.GrantX509Cert) + } + + // @@protoc_insertion_point(class_scope:calypso.GrantX509Cert) + private static final ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert(); + } + + public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public GrantX509Cert parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new GrantX509Cert(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_Write_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_Write_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_Read_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_Read_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_Authorise_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_Authorise_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_AuthoriseReply_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_AuthoriseReply_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_CreateLTS_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_CreateLTS_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_CreateLTSReply_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_CreateLTSReply_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_ReshareLTS_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_ReshareLTS_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_ReshareLTSReply_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_ReshareLTSReply_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_DecryptKey_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_DecryptKey_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_DecryptKeyReply_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_DecryptKeyReply_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_GetLTSReply_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_GetLTSReply_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_LtsInstanceInfo_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_LtsInstanceInfo_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_Auth_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_Auth_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_AuthByzCoin_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_AuthByzCoin_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_AuthX509Cert_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_AuthX509Cert_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_Grant_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_Grant_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_GrantByzCoin_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_GrantByzCoin_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_calypso_GrantX509Cert_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_calypso_GrantX509Cert_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\rcalypso.proto\022\007calypso\032\rbyzcoin.proto\032" + + "\nonet.proto\"q\n\005Write\022\014\n\004data\030\001 \002(\014\022\t\n\001u\030" + + "\002 \002(\014\022\014\n\004ubar\030\003 \002(\014\022\t\n\001e\030\004 \002(\014\022\t\n\001f\030\005 \002(" + + "\014\022\t\n\001c\030\006 \002(\014\022\021\n\textradata\030\007 \001(\014\022\r\n\005ltsid" + + "\030\010 \002(\014\"!\n\004Read\022\r\n\005write\030\001 \002(\014\022\n\n\002xc\030\002 \002(" + + "\014\"\036\n\tAuthorise\022\021\n\tbyzcoinid\030\001 \002(\014\"\020\n\016Aut" + + "horiseReply\"*\n\tCreateLTS\022\035\n\005proof\030\001 \002(\0132" + + "\016.byzcoin.Proof\"B\n\016CreateLTSReply\022\021\n\tbyz" + + "coinid\030\001 \002(\014\022\022\n\ninstanceid\030\002 \002(\014\022\t\n\001x\030\003 " + + "\002(\014\"+\n\nReshareLTS\022\035\n\005proof\030\001 \002(\0132\016.byzco" + + "in.Proof\"\021\n\017ReshareLTSReply\"I\n\nDecryptKe" + + "y\022\034\n\004read\030\001 \002(\0132\016.byzcoin.Proof\022\035\n\005write" + + "\030\002 \002(\0132\016.byzcoin.Proof\"8\n\017DecryptKeyRepl" + + "y\022\t\n\001c\030\001 \002(\014\022\017\n\007xhatenc\030\002 \002(\014\022\t\n\001x\030\003 \002(\014" + + "\"\034\n\013GetLTSReply\022\r\n\005ltsid\030\001 \002(\014\"/\n\017LtsIns" + + "tanceInfo\022\034\n\006roster\030\001 \002(\0132\014.onet.Roster\"" + + "Z\n\004Auth\022%\n\007byzcoin\030\001 \001(\0132\024.calypso.AuthB" + + "yzCoin\022+\n\014authx509cert\030\002 \001(\0132\025.calypso.A" + + "uthX509Cert\"-\n\013AuthByzCoin\022\021\n\tbyzcoinid\030" + + "\001 \002(\014\022\013\n\003ttl\030\002 \002(\004\"-\n\014AuthX509Cert\022\n\n\002ca" + + "\030\001 \003(\014\022\021\n\tthreshold\030\002 \002(\021\"Y\n\005Grant\022&\n\007by" + + "zcoin\030\001 \001(\0132\025.calypso.GrantByzCoin\022(\n\010x5" + + "09cert\030\002 \001(\0132\026.calypso.GrantX509Cert\"K\n\014" + + "GrantByzCoin\022\035\n\005write\030\001 \002(\0132\016.byzcoin.Pr" + + "oof\022\034\n\004read\030\002 \002(\0132\016.byzcoin.Proof\"5\n\rGra" + + "ntX509Cert\022\016\n\006secret\030\001 \002(\014\022\024\n\014certificat" + + "es\030\002 \003(\014B\"\n\027ch.epfl.dedis.lib.protoB\007Cal" + + "ypso" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + ch.epfl.dedis.lib.proto.ByzCoinProto.getDescriptor(), + ch.epfl.dedis.lib.proto.OnetProto.getDescriptor(), + }, assigner); + internal_static_calypso_Write_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_calypso_Write_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_Write_descriptor, + new java.lang.String[] { "Data", "U", "Ubar", "E", "F", "C", "Extradata", "Ltsid", }); + internal_static_calypso_Read_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_calypso_Read_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_Read_descriptor, + new java.lang.String[] { "Write", "Xc", }); + internal_static_calypso_Authorise_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_calypso_Authorise_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_Authorise_descriptor, + new java.lang.String[] { "Byzcoinid", }); + internal_static_calypso_AuthoriseReply_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_calypso_AuthoriseReply_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_AuthoriseReply_descriptor, + new java.lang.String[] { }); + internal_static_calypso_CreateLTS_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_calypso_CreateLTS_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_CreateLTS_descriptor, + new java.lang.String[] { "Proof", }); + internal_static_calypso_CreateLTSReply_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_calypso_CreateLTSReply_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_CreateLTSReply_descriptor, + new java.lang.String[] { "Byzcoinid", "Instanceid", "X", }); + internal_static_calypso_ReshareLTS_descriptor = + getDescriptor().getMessageTypes().get(6); + internal_static_calypso_ReshareLTS_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_ReshareLTS_descriptor, + new java.lang.String[] { "Proof", }); + internal_static_calypso_ReshareLTSReply_descriptor = + getDescriptor().getMessageTypes().get(7); + internal_static_calypso_ReshareLTSReply_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_ReshareLTSReply_descriptor, + new java.lang.String[] { }); + internal_static_calypso_DecryptKey_descriptor = + getDescriptor().getMessageTypes().get(8); + internal_static_calypso_DecryptKey_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_DecryptKey_descriptor, + new java.lang.String[] { "Read", "Write", }); internal_static_calypso_DecryptKeyReply_descriptor = getDescriptor().getMessageTypes().get(9); internal_static_calypso_DecryptKeyReply_fieldAccessorTable = new @@ -8697,6 +13441,42 @@ public com.google.protobuf.ExtensionRegistry assignDescriptors( com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_calypso_LtsInstanceInfo_descriptor, new java.lang.String[] { "Roster", }); + internal_static_calypso_Auth_descriptor = + getDescriptor().getMessageTypes().get(12); + internal_static_calypso_Auth_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_Auth_descriptor, + new java.lang.String[] { "Byzcoin", "Authx509Cert", }); + internal_static_calypso_AuthByzCoin_descriptor = + getDescriptor().getMessageTypes().get(13); + internal_static_calypso_AuthByzCoin_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_AuthByzCoin_descriptor, + new java.lang.String[] { "Byzcoinid", "Ttl", }); + internal_static_calypso_AuthX509Cert_descriptor = + getDescriptor().getMessageTypes().get(14); + internal_static_calypso_AuthX509Cert_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_AuthX509Cert_descriptor, + new java.lang.String[] { "Ca", "Threshold", }); + internal_static_calypso_Grant_descriptor = + getDescriptor().getMessageTypes().get(15); + internal_static_calypso_Grant_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_Grant_descriptor, + new java.lang.String[] { "Byzcoin", "X509Cert", }); + internal_static_calypso_GrantByzCoin_descriptor = + getDescriptor().getMessageTypes().get(16); + internal_static_calypso_GrantByzCoin_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_GrantByzCoin_descriptor, + new java.lang.String[] { "Write", "Read", }); + internal_static_calypso_GrantX509Cert_descriptor = + getDescriptor().getMessageTypes().get(17); + internal_static_calypso_GrantX509Cert_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_calypso_GrantX509Cert_descriptor, + new java.lang.String[] { "Secret", "Certificates", }); ch.epfl.dedis.lib.proto.ByzCoinProto.getDescriptor(); ch.epfl.dedis.lib.proto.OnetProto.getDescriptor(); } diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/DarcProto.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/DarcProto.java index f458f464cf..942bb2861b 100644 --- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/DarcProto.java +++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/DarcProto.java @@ -246,7 +246,6 @@ private Darc(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } private Darc() { - version_ = 0L; description_ = com.google.protobuf.ByteString.EMPTY; baseid_ = com.google.protobuf.ByteString.EMPTY; previd_ = com.google.protobuf.ByteString.EMPTY; @@ -300,7 +299,7 @@ private Darc( } case 42: { ch.epfl.dedis.lib.proto.DarcProto.Rules.Builder subBuilder = null; - if (((bitField0_ & 0x00000010) == 0x00000010)) { + if (((bitField0_ & 0x00000010) != 0)) { subBuilder = rules_.toBuilder(); } rules_ = input.readMessage(ch.epfl.dedis.lib.proto.DarcProto.Rules.parser(), extensionRegistry); @@ -312,7 +311,7 @@ private Darc( break; } case 50: { - if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) { + if (!((mutable_bitField0_ & 0x00000020) != 0)) { signatures_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000020; } @@ -321,7 +320,7 @@ private Darc( break; } case 58: { - if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) { + if (!((mutable_bitField0_ & 0x00000040) != 0)) { verificationdarcs_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000040; } @@ -344,10 +343,10 @@ private Darc( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { - if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) { + if (((mutable_bitField0_ & 0x00000020) != 0)) { signatures_ = java.util.Collections.unmodifiableList(signatures_); } - if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) { + if (((mutable_bitField0_ & 0x00000040) != 0)) { verificationdarcs_ = java.util.Collections.unmodifiableList(verificationdarcs_); } this.unknownFields = unknownFields.build(); @@ -379,7 +378,7 @@ private Darc( * required uint64 version = 1; */ public boolean hasVersion() { - return ((bitField0_ & 0x00000001) == 0x00000001); + return ((bitField0_ & 0x00000001) != 0); } /** *
@@ -405,7 +404,7 @@ public long getVersion() {
      * required bytes description = 2;
      */
     public boolean hasDescription() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -431,7 +430,7 @@ public com.google.protobuf.ByteString getDescription() {
      * optional bytes baseid = 3;
      */
     public boolean hasBaseid() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -455,7 +454,7 @@ public com.google.protobuf.ByteString getBaseid() {
      * required bytes previd = 4;
      */
     public boolean hasPrevid() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * 
@@ -478,7 +477,7 @@ public com.google.protobuf.ByteString getPrevid() {
      * required .darc.Rules rules = 5;
      */
     public boolean hasRules() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * 
@@ -677,19 +676,19 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeUInt64(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, description_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, baseid_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeBytes(4, previd_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         output.writeMessage(5, getRules());
       }
       for (int i = 0; i < signatures_.size(); i++) {
@@ -707,23 +706,23 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(1, version_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, description_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, baseid_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(4, previd_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(5, getRules());
       }
@@ -750,38 +749,37 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.Darc other = (ch.epfl.dedis.lib.proto.DarcProto.Darc) obj;
 
-      boolean result = true;
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && (getVersion()
-            == other.getVersion());
+        if (getVersion()
+            != other.getVersion()) return false;
       }
-      result = result && (hasDescription() == other.hasDescription());
+      if (hasDescription() != other.hasDescription()) return false;
       if (hasDescription()) {
-        result = result && getDescription()
-            .equals(other.getDescription());
+        if (!getDescription()
+            .equals(other.getDescription())) return false;
       }
-      result = result && (hasBaseid() == other.hasBaseid());
+      if (hasBaseid() != other.hasBaseid()) return false;
       if (hasBaseid()) {
-        result = result && getBaseid()
-            .equals(other.getBaseid());
+        if (!getBaseid()
+            .equals(other.getBaseid())) return false;
       }
-      result = result && (hasPrevid() == other.hasPrevid());
+      if (hasPrevid() != other.hasPrevid()) return false;
       if (hasPrevid()) {
-        result = result && getPrevid()
-            .equals(other.getPrevid());
+        if (!getPrevid()
+            .equals(other.getPrevid())) return false;
       }
-      result = result && (hasRules() == other.hasRules());
+      if (hasRules() != other.hasRules()) return false;
       if (hasRules()) {
-        result = result && getRules()
-            .equals(other.getRules());
-      }
-      result = result && getSignaturesList()
-          .equals(other.getSignaturesList());
-      result = result && getVerificationdarcsList()
-          .equals(other.getVerificationdarcsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+        if (!getRules()
+            .equals(other.getRules())) return false;
+      }
+      if (!getSignaturesList()
+          .equals(other.getSignaturesList())) return false;
+      if (!getVerificationdarcsList()
+          .equals(other.getVerificationdarcsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -1016,32 +1014,32 @@ public ch.epfl.dedis.lib.proto.DarcProto.Darc buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.Darc result = new ch.epfl.dedis.lib.proto.DarcProto.Darc(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.version_ = version_;
           to_bitField0_ |= 0x00000001;
         }
-        result.version_ = version_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.description_ = description_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.baseid_ = baseid_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
           to_bitField0_ |= 0x00000008;
         }
         result.previd_ = previd_;
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((from_bitField0_ & 0x00000010) != 0)) {
+          if (rulesBuilder_ == null) {
+            result.rules_ = rules_;
+          } else {
+            result.rules_ = rulesBuilder_.build();
+          }
           to_bitField0_ |= 0x00000010;
         }
-        if (rulesBuilder_ == null) {
-          result.rules_ = rules_;
-        } else {
-          result.rules_ = rulesBuilder_.build();
-        }
         if (signaturesBuilder_ == null) {
-          if (((bitField0_ & 0x00000020) == 0x00000020)) {
+          if (((bitField0_ & 0x00000020) != 0)) {
             signatures_ = java.util.Collections.unmodifiableList(signatures_);
             bitField0_ = (bitField0_ & ~0x00000020);
           }
@@ -1050,7 +1048,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Darc buildPartial() {
           result.signatures_ = signaturesBuilder_.build();
         }
         if (verificationdarcsBuilder_ == null) {
-          if (((bitField0_ & 0x00000040) == 0x00000040)) {
+          if (((bitField0_ & 0x00000040) != 0)) {
             verificationdarcs_ = java.util.Collections.unmodifiableList(verificationdarcs_);
             bitField0_ = (bitField0_ & ~0x00000040);
           }
@@ -1065,35 +1063,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.Darc buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -1239,7 +1237,7 @@ public Builder mergeFrom(
        * required uint64 version = 1;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -1292,7 +1290,7 @@ public Builder clearVersion() {
        * required bytes description = 2;
        */
       public boolean hasDescription() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -1350,7 +1348,7 @@ public Builder clearDescription() {
        * optional bytes baseid = 3;
        */
       public boolean hasBaseid() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -1404,7 +1402,7 @@ public Builder clearBaseid() {
        * required bytes previd = 4;
        */
       public boolean hasPrevid() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * 
@@ -1446,7 +1444,7 @@ public Builder clearPrevid() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.DarcProto.Rules rules_ = null;
+      private ch.epfl.dedis.lib.proto.DarcProto.Rules rules_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.DarcProto.Rules, ch.epfl.dedis.lib.proto.DarcProto.Rules.Builder, ch.epfl.dedis.lib.proto.DarcProto.RulesOrBuilder> rulesBuilder_;
       /**
@@ -1457,7 +1455,7 @@ public Builder clearPrevid() {
        * required .darc.Rules rules = 5;
        */
       public boolean hasRules() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return ((bitField0_ & 0x00000010) != 0);
       }
       /**
        * 
@@ -1520,7 +1518,7 @@ public Builder setRules(
        */
       public Builder mergeRules(ch.epfl.dedis.lib.proto.DarcProto.Rules value) {
         if (rulesBuilder_ == null) {
-          if (((bitField0_ & 0x00000010) == 0x00000010) &&
+          if (((bitField0_ & 0x00000010) != 0) &&
               rules_ != null &&
               rules_ != ch.epfl.dedis.lib.proto.DarcProto.Rules.getDefaultInstance()) {
             rules_ =
@@ -1603,7 +1601,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.RulesOrBuilder getRulesOrBuilder() {
       private java.util.List signatures_ =
         java.util.Collections.emptyList();
       private void ensureSignaturesIsMutable() {
-        if (!((bitField0_ & 0x00000020) == 0x00000020)) {
+        if (!((bitField0_ & 0x00000020) != 0)) {
           signatures_ = new java.util.ArrayList(signatures_);
           bitField0_ |= 0x00000020;
          }
@@ -1940,7 +1938,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Signature.Builder addSignaturesBuilder(
           signaturesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.DarcProto.Signature, ch.epfl.dedis.lib.proto.DarcProto.Signature.Builder, ch.epfl.dedis.lib.proto.DarcProto.SignatureOrBuilder>(
                   signatures_,
-                  ((bitField0_ & 0x00000020) == 0x00000020),
+                  ((bitField0_ & 0x00000020) != 0),
                   getParentForChildren(),
                   isClean());
           signatures_ = null;
@@ -1951,7 +1949,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Signature.Builder addSignaturesBuilder(
       private java.util.List verificationdarcs_ =
         java.util.Collections.emptyList();
       private void ensureVerificationdarcsIsMutable() {
-        if (!((bitField0_ & 0x00000040) == 0x00000040)) {
+        if (!((bitField0_ & 0x00000040) != 0)) {
           verificationdarcs_ = new java.util.ArrayList(verificationdarcs_);
           bitField0_ |= 0x00000040;
          }
@@ -2288,7 +2286,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Darc.Builder addVerificationdarcsBuilde
           verificationdarcsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.DarcProto.Darc, ch.epfl.dedis.lib.proto.DarcProto.Darc.Builder, ch.epfl.dedis.lib.proto.DarcProto.DarcOrBuilder>(
                   verificationdarcs_,
-                  ((bitField0_ & 0x00000040) == 0x00000040),
+                  ((bitField0_ & 0x00000040) != 0),
                   getParentForChildren(),
                   isClean());
           verificationdarcs_ = null;
@@ -2498,7 +2496,7 @@ private Identity(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = darc_.toBuilder();
               }
               darc_ = input.readMessage(ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc.parser(), extensionRegistry);
@@ -2511,7 +2509,7 @@ private Identity(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = ed25519_.toBuilder();
               }
               ed25519_ = input.readMessage(ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519.parser(), extensionRegistry);
@@ -2524,7 +2522,7 @@ private Identity(
             }
             case 26: {
               ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (((bitField0_ & 0x00000004) != 0)) {
                 subBuilder = x509Ec_.toBuilder();
               }
               x509Ec_ = input.readMessage(ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC.parser(), extensionRegistry);
@@ -2537,7 +2535,7 @@ private Identity(
             }
             case 34: {
               ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000008) == 0x00000008)) {
+              if (((bitField0_ & 0x00000008) != 0)) {
                 subBuilder = proxy_.toBuilder();
               }
               proxy_ = input.readMessage(ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy.parser(), extensionRegistry);
@@ -2591,7 +2589,7 @@ private Identity(
      * optional .darc.IdentityDarc darc = 1;
      */
     public boolean hasDarc() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -2624,7 +2622,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityDarcOrBuilder getDarcOrBuilder(
      * optional .darc.IdentityEd25519 ed25519 = 2;
      */
     public boolean hasEd25519() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -2657,7 +2655,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519OrBuilder getEd25519OrBu
      * optional .darc.IdentityX509EC x509ec = 3;
      */
     public boolean hasX509Ec() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -2690,7 +2688,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityX509ECOrBuilder getX509EcOrBuil
      * optional .darc.IdentityProxy proxy = 4;
      */
     public boolean hasProxy() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * 
@@ -2751,16 +2749,16 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getDarc());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getEd25519());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeMessage(3, getX509Ec());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeMessage(4, getProxy());
       }
       unknownFields.writeTo(output);
@@ -2772,19 +2770,19 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getDarc());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getEd25519());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getX509Ec());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(4, getProxy());
       }
@@ -2803,29 +2801,28 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.Identity other = (ch.epfl.dedis.lib.proto.DarcProto.Identity) obj;
 
-      boolean result = true;
-      result = result && (hasDarc() == other.hasDarc());
+      if (hasDarc() != other.hasDarc()) return false;
       if (hasDarc()) {
-        result = result && getDarc()
-            .equals(other.getDarc());
+        if (!getDarc()
+            .equals(other.getDarc())) return false;
       }
-      result = result && (hasEd25519() == other.hasEd25519());
+      if (hasEd25519() != other.hasEd25519()) return false;
       if (hasEd25519()) {
-        result = result && getEd25519()
-            .equals(other.getEd25519());
+        if (!getEd25519()
+            .equals(other.getEd25519())) return false;
       }
-      result = result && (hasX509Ec() == other.hasX509Ec());
+      if (hasX509Ec() != other.hasX509Ec()) return false;
       if (hasX509Ec()) {
-        result = result && getX509Ec()
-            .equals(other.getX509Ec());
+        if (!getX509Ec()
+            .equals(other.getX509Ec())) return false;
       }
-      result = result && (hasProxy() == other.hasProxy());
+      if (hasProxy() != other.hasProxy()) return false;
       if (hasProxy()) {
-        result = result && getProxy()
-            .equals(other.getProxy());
+        if (!getProxy()
+            .equals(other.getProxy())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -3045,38 +3042,38 @@ public ch.epfl.dedis.lib.proto.DarcProto.Identity buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.Identity result = new ch.epfl.dedis.lib.proto.DarcProto.Identity(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (darcBuilder_ == null) {
+            result.darc_ = darc_;
+          } else {
+            result.darc_ = darcBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (darcBuilder_ == null) {
-          result.darc_ = darc_;
-        } else {
-          result.darc_ = darcBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (ed25519Builder_ == null) {
+            result.ed25519_ = ed25519_;
+          } else {
+            result.ed25519_ = ed25519Builder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (ed25519Builder_ == null) {
-          result.ed25519_ = ed25519_;
-        } else {
-          result.ed25519_ = ed25519Builder_.build();
-        }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          if (x509EcBuilder_ == null) {
+            result.x509Ec_ = x509Ec_;
+          } else {
+            result.x509Ec_ = x509EcBuilder_.build();
+          }
           to_bitField0_ |= 0x00000004;
         }
-        if (x509EcBuilder_ == null) {
-          result.x509Ec_ = x509Ec_;
-        } else {
-          result.x509Ec_ = x509EcBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          if (proxyBuilder_ == null) {
+            result.proxy_ = proxy_;
+          } else {
+            result.proxy_ = proxyBuilder_.build();
+          }
           to_bitField0_ |= 0x00000008;
         }
-        if (proxyBuilder_ == null) {
-          result.proxy_ = proxy_;
-        } else {
-          result.proxy_ = proxyBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -3084,35 +3081,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.Identity buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -3188,7 +3185,7 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc darc_ = null;
+      private ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc darc_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc, ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc.Builder, ch.epfl.dedis.lib.proto.DarcProto.IdentityDarcOrBuilder> darcBuilder_;
       /**
@@ -3199,7 +3196,7 @@ public Builder mergeFrom(
        * optional .darc.IdentityDarc darc = 1;
        */
       public boolean hasDarc() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -3262,7 +3259,7 @@ public Builder setDarc(
        */
       public Builder mergeDarc(ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc value) {
         if (darcBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               darc_ != null &&
               darc_ != ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc.getDefaultInstance()) {
             darc_ =
@@ -3342,7 +3339,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityDarcOrBuilder getDarcOrBuilder(
         return darcBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519 ed25519_ = null;
+      private ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519 ed25519_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519, ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519.Builder, ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519OrBuilder> ed25519Builder_;
       /**
@@ -3353,7 +3350,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityDarcOrBuilder getDarcOrBuilder(
        * optional .darc.IdentityEd25519 ed25519 = 2;
        */
       public boolean hasEd25519() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -3416,7 +3413,7 @@ public Builder setEd25519(
        */
       public Builder mergeEd25519(ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519 value) {
         if (ed25519Builder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               ed25519_ != null &&
               ed25519_ != ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519.getDefaultInstance()) {
             ed25519_ =
@@ -3496,7 +3493,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519OrBuilder getEd25519OrBu
         return ed25519Builder_;
       }
 
-      private ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC x509Ec_ = null;
+      private ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC x509Ec_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC, ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC.Builder, ch.epfl.dedis.lib.proto.DarcProto.IdentityX509ECOrBuilder> x509EcBuilder_;
       /**
@@ -3507,7 +3504,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519OrBuilder getEd25519OrBu
        * optional .darc.IdentityX509EC x509ec = 3;
        */
       public boolean hasX509Ec() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -3570,7 +3567,7 @@ public Builder setX509Ec(
        */
       public Builder mergeX509Ec(ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC value) {
         if (x509EcBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+          if (((bitField0_ & 0x00000004) != 0) &&
               x509Ec_ != null &&
               x509Ec_ != ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC.getDefaultInstance()) {
             x509Ec_ =
@@ -3650,7 +3647,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityX509ECOrBuilder getX509EcOrBuil
         return x509EcBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy proxy_ = null;
+      private ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy proxy_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy, ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy.Builder, ch.epfl.dedis.lib.proto.DarcProto.IdentityProxyOrBuilder> proxyBuilder_;
       /**
@@ -3661,7 +3658,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityX509ECOrBuilder getX509EcOrBuil
        * optional .darc.IdentityProxy proxy = 4;
        */
       public boolean hasProxy() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * 
@@ -3724,7 +3721,7 @@ public Builder setProxy(
        */
       public Builder mergeProxy(ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy value) {
         if (proxyBuilder_ == null) {
-          if (((bitField0_ & 0x00000008) == 0x00000008) &&
+          if (((bitField0_ & 0x00000008) != 0) &&
               proxy_ != null &&
               proxy_ != ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy.getDefaultInstance()) {
             proxy_ =
@@ -3957,7 +3954,7 @@ private IdentityEd25519(
      * required bytes point = 1;
      */
     public boolean hasPoint() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes point = 1;
@@ -3984,7 +3981,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, point_);
       }
       unknownFields.writeTo(output);
@@ -3996,7 +3993,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, point_);
       }
@@ -4015,14 +4012,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519 other = (ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519) obj;
 
-      boolean result = true;
-      result = result && (hasPoint() == other.hasPoint());
+      if (hasPoint() != other.hasPoint()) return false;
       if (hasPoint()) {
-        result = result && getPoint()
-            .equals(other.getPoint());
+        if (!getPoint()
+            .equals(other.getPoint())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -4203,7 +4199,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519 buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519 result = new ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.point_ = point_;
@@ -4214,35 +4210,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityEd25519 buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -4297,7 +4293,7 @@ public Builder mergeFrom(
        * required bytes point = 1;
        */
       public boolean hasPoint() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes point = 1;
@@ -4480,7 +4476,7 @@ private IdentityX509EC(
      * required bytes public = 1;
      */
     public boolean hasPublic() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes public = 1;
@@ -4507,7 +4503,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, public_);
       }
       unknownFields.writeTo(output);
@@ -4519,7 +4515,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, public_);
       }
@@ -4538,14 +4534,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC other = (ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC) obj;
 
-      boolean result = true;
-      result = result && (hasPublic() == other.hasPublic());
+      if (hasPublic() != other.hasPublic()) return false;
       if (hasPublic()) {
-        result = result && getPublic()
-            .equals(other.getPublic());
+        if (!getPublic()
+            .equals(other.getPublic())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -4726,7 +4721,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC result = new ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.public_ = public_;
@@ -4737,35 +4732,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityX509EC buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -4820,7 +4815,7 @@ public Builder mergeFrom(
        * required bytes public = 1;
        */
       public boolean hasPublic() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes public = 1;
@@ -5025,7 +5020,7 @@ private IdentityProxy(
      * required string data = 1;
      */
     public boolean hasData() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required string data = 1;
@@ -5067,7 +5062,7 @@ public java.lang.String getData() {
      * required bytes public = 2;
      */
     public boolean hasPublic() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes public = 2;
@@ -5098,10 +5093,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, data_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, public_);
       }
       unknownFields.writeTo(output);
@@ -5113,10 +5108,10 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, data_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, public_);
       }
@@ -5135,19 +5130,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy other = (ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy) obj;
 
-      boolean result = true;
-      result = result && (hasData() == other.hasData());
+      if (hasData() != other.hasData()) return false;
       if (hasData()) {
-        result = result && getData()
-            .equals(other.getData());
+        if (!getData()
+            .equals(other.getData())) return false;
       }
-      result = result && (hasPublic() == other.hasPublic());
+      if (hasPublic() != other.hasPublic()) return false;
       if (hasPublic()) {
-        result = result && getPublic()
-            .equals(other.getPublic());
+        if (!getPublic()
+            .equals(other.getPublic())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -5335,11 +5329,11 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy result = new ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.data_ = data_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.public_ = public_;
@@ -5350,35 +5344,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityProxy buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -5441,7 +5435,7 @@ public Builder mergeFrom(
        * required string data = 1;
        */
       public boolean hasData() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required string data = 1;
@@ -5517,7 +5511,7 @@ public Builder setDataBytes(
        * required bytes public = 2;
        */
       public boolean hasPublic() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes public = 2;
@@ -5713,7 +5707,7 @@ private IdentityDarc(
      * required bytes id = 1;
      */
     public boolean hasId() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -5744,7 +5738,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, id_);
       }
       unknownFields.writeTo(output);
@@ -5756,7 +5750,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, id_);
       }
@@ -5775,14 +5769,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc other = (ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc) obj;
 
-      boolean result = true;
-      result = result && (hasId() == other.hasId());
+      if (hasId() != other.hasId()) return false;
       if (hasId()) {
-        result = result && getId()
-            .equals(other.getId());
+        if (!getId()
+            .equals(other.getId())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -5964,7 +5957,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc result = new ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.id_ = id_;
@@ -5975,35 +5968,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.IdentityDarc buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -6062,7 +6055,7 @@ public Builder mergeFrom(
        * required bytes id = 1;
        */
       public boolean hasId() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -6254,7 +6247,7 @@ private Signature(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.DarcProto.Identity.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = signer_.toBuilder();
               }
               signer_ = input.readMessage(ch.epfl.dedis.lib.proto.DarcProto.Identity.parser(), extensionRegistry);
@@ -6308,7 +6301,7 @@ private Signature(
      * required bytes signature = 1;
      */
     public boolean hasSignature() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -6331,7 +6324,7 @@ public com.google.protobuf.ByteString getSignature() {
      * required .darc.Identity signer = 2;
      */
     public boolean hasSigner() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -6380,10 +6373,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, signature_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getSigner());
       }
       unknownFields.writeTo(output);
@@ -6395,11 +6388,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, signature_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getSigner());
       }
@@ -6418,19 +6411,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.Signature other = (ch.epfl.dedis.lib.proto.DarcProto.Signature) obj;
 
-      boolean result = true;
-      result = result && (hasSignature() == other.hasSignature());
+      if (hasSignature() != other.hasSignature()) return false;
       if (hasSignature()) {
-        result = result && getSignature()
-            .equals(other.getSignature());
+        if (!getSignature()
+            .equals(other.getSignature())) return false;
       }
-      result = result && (hasSigner() == other.hasSigner());
+      if (hasSigner() != other.hasSigner()) return false;
       if (hasSigner()) {
-        result = result && getSigner()
-            .equals(other.getSigner());
+        if (!getSigner()
+            .equals(other.getSigner())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -6623,18 +6615,18 @@ public ch.epfl.dedis.lib.proto.DarcProto.Signature buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.Signature result = new ch.epfl.dedis.lib.proto.DarcProto.Signature(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.signature_ = signature_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (signerBuilder_ == null) {
+            result.signer_ = signer_;
+          } else {
+            result.signer_ = signerBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (signerBuilder_ == null) {
-          result.signer_ = signer_;
-        } else {
-          result.signer_ = signerBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -6642,35 +6634,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.Signature buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -6738,7 +6730,7 @@ public Builder mergeFrom(
        * required bytes signature = 1;
        */
       public boolean hasSignature() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -6780,7 +6772,7 @@ public Builder clearSignature() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.DarcProto.Identity signer_ = null;
+      private ch.epfl.dedis.lib.proto.DarcProto.Identity signer_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.DarcProto.Identity, ch.epfl.dedis.lib.proto.DarcProto.Identity.Builder, ch.epfl.dedis.lib.proto.DarcProto.IdentityOrBuilder> signerBuilder_;
       /**
@@ -6791,7 +6783,7 @@ public Builder clearSignature() {
        * required .darc.Identity signer = 2;
        */
       public boolean hasSigner() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -6854,7 +6846,7 @@ public Builder setSigner(
        */
       public Builder mergeSigner(ch.epfl.dedis.lib.proto.DarcProto.Identity value) {
         if (signerBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               signer_ != null &&
               signer_ != ch.epfl.dedis.lib.proto.DarcProto.Identity.getDefaultInstance()) {
             signer_ =
@@ -7074,7 +7066,7 @@ private Signer(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = ed25519_.toBuilder();
               }
               ed25519_ = input.readMessage(ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519.parser(), extensionRegistry);
@@ -7087,7 +7079,7 @@ private Signer(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = x509Ec_.toBuilder();
               }
               x509Ec_ = input.readMessage(ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC.parser(), extensionRegistry);
@@ -7100,7 +7092,7 @@ private Signer(
             }
             case 26: {
               ch.epfl.dedis.lib.proto.DarcProto.SignerProxy.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (((bitField0_ & 0x00000004) != 0)) {
                 subBuilder = proxy_.toBuilder();
               }
               proxy_ = input.readMessage(ch.epfl.dedis.lib.proto.DarcProto.SignerProxy.parser(), extensionRegistry);
@@ -7150,7 +7142,7 @@ private Signer(
      * optional .darc.SignerEd25519 ed25519 = 1;
      */
     public boolean hasEd25519() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * optional .darc.SignerEd25519 ed25519 = 1;
@@ -7171,7 +7163,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519OrBuilder getEd25519OrBuil
      * optional .darc.SignerX509EC x509ec = 2;
      */
     public boolean hasX509Ec() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * optional .darc.SignerX509EC x509ec = 2;
@@ -7192,7 +7184,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.SignerX509ECOrBuilder getX509EcOrBuilde
      * optional .darc.SignerProxy proxy = 3;
      */
     public boolean hasProxy() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * optional .darc.SignerProxy proxy = 3;
@@ -7239,13 +7231,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getEd25519());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getX509Ec());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeMessage(3, getProxy());
       }
       unknownFields.writeTo(output);
@@ -7257,15 +7249,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getEd25519());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getX509Ec());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getProxy());
       }
@@ -7284,24 +7276,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.Signer other = (ch.epfl.dedis.lib.proto.DarcProto.Signer) obj;
 
-      boolean result = true;
-      result = result && (hasEd25519() == other.hasEd25519());
+      if (hasEd25519() != other.hasEd25519()) return false;
       if (hasEd25519()) {
-        result = result && getEd25519()
-            .equals(other.getEd25519());
+        if (!getEd25519()
+            .equals(other.getEd25519())) return false;
       }
-      result = result && (hasX509Ec() == other.hasX509Ec());
+      if (hasX509Ec() != other.hasX509Ec()) return false;
       if (hasX509Ec()) {
-        result = result && getX509Ec()
-            .equals(other.getX509Ec());
+        if (!getX509Ec()
+            .equals(other.getX509Ec())) return false;
       }
-      result = result && (hasProxy() == other.hasProxy());
+      if (hasProxy() != other.hasProxy()) return false;
       if (hasProxy()) {
-        result = result && getProxy()
-            .equals(other.getProxy());
+        if (!getProxy()
+            .equals(other.getProxy())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -7509,30 +7500,30 @@ public ch.epfl.dedis.lib.proto.DarcProto.Signer buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.Signer result = new ch.epfl.dedis.lib.proto.DarcProto.Signer(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (ed25519Builder_ == null) {
+            result.ed25519_ = ed25519_;
+          } else {
+            result.ed25519_ = ed25519Builder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (ed25519Builder_ == null) {
-          result.ed25519_ = ed25519_;
-        } else {
-          result.ed25519_ = ed25519Builder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (x509EcBuilder_ == null) {
+            result.x509Ec_ = x509Ec_;
+          } else {
+            result.x509Ec_ = x509EcBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (x509EcBuilder_ == null) {
-          result.x509Ec_ = x509Ec_;
-        } else {
-          result.x509Ec_ = x509EcBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          if (proxyBuilder_ == null) {
+            result.proxy_ = proxy_;
+          } else {
+            result.proxy_ = proxyBuilder_.build();
+          }
           to_bitField0_ |= 0x00000004;
         }
-        if (proxyBuilder_ == null) {
-          result.proxy_ = proxy_;
-        } else {
-          result.proxy_ = proxyBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -7540,35 +7531,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.Signer buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -7636,14 +7627,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519 ed25519_ = null;
+      private ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519 ed25519_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519, ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519.Builder, ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519OrBuilder> ed25519Builder_;
       /**
        * optional .darc.SignerEd25519 ed25519 = 1;
        */
       public boolean hasEd25519() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * optional .darc.SignerEd25519 ed25519 = 1;
@@ -7690,7 +7681,7 @@ public Builder setEd25519(
        */
       public Builder mergeEd25519(ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519 value) {
         if (ed25519Builder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               ed25519_ != null &&
               ed25519_ != ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519.getDefaultInstance()) {
             ed25519_ =
@@ -7754,14 +7745,14 @@ public ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519OrBuilder getEd25519OrBuil
         return ed25519Builder_;
       }
 
-      private ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC x509Ec_ = null;
+      private ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC x509Ec_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC, ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC.Builder, ch.epfl.dedis.lib.proto.DarcProto.SignerX509ECOrBuilder> x509EcBuilder_;
       /**
        * optional .darc.SignerX509EC x509ec = 2;
        */
       public boolean hasX509Ec() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * optional .darc.SignerX509EC x509ec = 2;
@@ -7808,7 +7799,7 @@ public Builder setX509Ec(
        */
       public Builder mergeX509Ec(ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC value) {
         if (x509EcBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               x509Ec_ != null &&
               x509Ec_ != ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC.getDefaultInstance()) {
             x509Ec_ =
@@ -7872,14 +7863,14 @@ public ch.epfl.dedis.lib.proto.DarcProto.SignerX509ECOrBuilder getX509EcOrBuilde
         return x509EcBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.DarcProto.SignerProxy proxy_ = null;
+      private ch.epfl.dedis.lib.proto.DarcProto.SignerProxy proxy_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.DarcProto.SignerProxy, ch.epfl.dedis.lib.proto.DarcProto.SignerProxy.Builder, ch.epfl.dedis.lib.proto.DarcProto.SignerProxyOrBuilder> proxyBuilder_;
       /**
        * optional .darc.SignerProxy proxy = 3;
        */
       public boolean hasProxy() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * optional .darc.SignerProxy proxy = 3;
@@ -7926,7 +7917,7 @@ public Builder setProxy(
        */
       public Builder mergeProxy(ch.epfl.dedis.lib.proto.DarcProto.SignerProxy value) {
         if (proxyBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+          if (((bitField0_ & 0x00000004) != 0) &&
               proxy_ != null &&
               proxy_ != ch.epfl.dedis.lib.proto.DarcProto.SignerProxy.getDefaultInstance()) {
             proxy_ =
@@ -8158,7 +8149,7 @@ private SignerEd25519(
      * required bytes point = 1;
      */
     public boolean hasPoint() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes point = 1;
@@ -8173,7 +8164,7 @@ public com.google.protobuf.ByteString getPoint() {
      * required bytes secret = 2;
      */
     public boolean hasSecret() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes secret = 2;
@@ -8204,10 +8195,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, point_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, secret_);
       }
       unknownFields.writeTo(output);
@@ -8219,11 +8210,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, point_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, secret_);
       }
@@ -8242,19 +8233,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519 other = (ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519) obj;
 
-      boolean result = true;
-      result = result && (hasPoint() == other.hasPoint());
+      if (hasPoint() != other.hasPoint()) return false;
       if (hasPoint()) {
-        result = result && getPoint()
-            .equals(other.getPoint());
+        if (!getPoint()
+            .equals(other.getPoint())) return false;
       }
-      result = result && (hasSecret() == other.hasSecret());
+      if (hasSecret() != other.hasSecret()) return false;
       if (hasSecret()) {
-        result = result && getSecret()
-            .equals(other.getSecret());
+        if (!getSecret()
+            .equals(other.getSecret())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -8441,11 +8431,11 @@ public ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519 buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519 result = new ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.point_ = point_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.secret_ = secret_;
@@ -8456,35 +8446,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.SignerEd25519 buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -8545,7 +8535,7 @@ public Builder mergeFrom(
        * required bytes point = 1;
        */
       public boolean hasPoint() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes point = 1;
@@ -8580,7 +8570,7 @@ public Builder clearPoint() {
        * required bytes secret = 2;
        */
       public boolean hasSecret() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes secret = 2;
@@ -8764,7 +8754,7 @@ private SignerX509EC(
      * required bytes point = 1;
      */
     public boolean hasPoint() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes point = 1;
@@ -8791,7 +8781,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, point_);
       }
       unknownFields.writeTo(output);
@@ -8803,7 +8793,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, point_);
       }
@@ -8822,14 +8812,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC other = (ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC) obj;
 
-      boolean result = true;
-      result = result && (hasPoint() == other.hasPoint());
+      if (hasPoint() != other.hasPoint()) return false;
       if (hasPoint()) {
-        result = result && getPoint()
-            .equals(other.getPoint());
+        if (!getPoint()
+            .equals(other.getPoint())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -9011,7 +9000,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC result = new ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.point_ = point_;
@@ -9022,35 +9011,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.SignerX509EC buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -9105,7 +9094,7 @@ public Builder mergeFrom(
        * required bytes point = 1;
        */
       public boolean hasPoint() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes point = 1;
@@ -9310,7 +9299,7 @@ private SignerProxy(
      * required string data = 1;
      */
     public boolean hasData() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required string data = 1;
@@ -9352,7 +9341,7 @@ public java.lang.String getData() {
      * required bytes public = 2;
      */
     public boolean hasPublic() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes public = 2;
@@ -9383,10 +9372,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, data_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, public_);
       }
       unknownFields.writeTo(output);
@@ -9398,10 +9387,10 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, data_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, public_);
       }
@@ -9420,19 +9409,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.SignerProxy other = (ch.epfl.dedis.lib.proto.DarcProto.SignerProxy) obj;
 
-      boolean result = true;
-      result = result && (hasData() == other.hasData());
+      if (hasData() != other.hasData()) return false;
       if (hasData()) {
-        result = result && getData()
-            .equals(other.getData());
+        if (!getData()
+            .equals(other.getData())) return false;
       }
-      result = result && (hasPublic() == other.hasPublic());
+      if (hasPublic() != other.hasPublic()) return false;
       if (hasPublic()) {
-        result = result && getPublic()
-            .equals(other.getPublic());
+        if (!getPublic()
+            .equals(other.getPublic())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -9620,11 +9608,11 @@ public ch.epfl.dedis.lib.proto.DarcProto.SignerProxy buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.SignerProxy result = new ch.epfl.dedis.lib.proto.DarcProto.SignerProxy(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.data_ = data_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.public_ = public_;
@@ -9635,35 +9623,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.SignerProxy buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -9726,7 +9714,7 @@ public Builder mergeFrom(
        * required string data = 1;
        */
       public boolean hasData() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required string data = 1;
@@ -9802,7 +9790,7 @@ public Builder setDataBytes(
        * required bytes public = 2;
        */
       public boolean hasPublic() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes public = 2;
@@ -10022,7 +10010,7 @@ private Request(
               break;
             }
             case 34: {
-              if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+              if (!((mutable_bitField0_ & 0x00000008) != 0)) {
                 identities_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000008;
               }
@@ -10031,7 +10019,7 @@ private Request(
               break;
             }
             case 42: {
-              if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+              if (!((mutable_bitField0_ & 0x00000010) != 0)) {
                 signatures_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000010;
               }
@@ -10053,11 +10041,11 @@ private Request(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((mutable_bitField0_ & 0x00000008) != 0)) {
           identities_ = java.util.Collections.unmodifiableList(identities_);
         }
-        if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
-          signatures_ = java.util.Collections.unmodifiableList(signatures_);
+        if (((mutable_bitField0_ & 0x00000010) != 0)) {
+          signatures_ = java.util.Collections.unmodifiableList(signatures_); // C
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -10083,7 +10071,7 @@ private Request(
      * required bytes baseid = 1;
      */
     public boolean hasBaseid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes baseid = 1;
@@ -10098,7 +10086,7 @@ public com.google.protobuf.ByteString getBaseid() {
      * required string action = 2;
      */
     public boolean hasAction() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required string action = 2;
@@ -10140,7 +10128,7 @@ public java.lang.String getAction() {
      * required bytes msg = 3;
      */
     public boolean hasMsg() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required bytes msg = 3;
@@ -10238,13 +10226,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, baseid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 2, action_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, msg_);
       }
       for (int i = 0; i < identities_.size(); i++) {
@@ -10262,14 +10250,14 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, baseid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, action_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, msg_);
       }
@@ -10301,28 +10289,27 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.Request other = (ch.epfl.dedis.lib.proto.DarcProto.Request) obj;
 
-      boolean result = true;
-      result = result && (hasBaseid() == other.hasBaseid());
+      if (hasBaseid() != other.hasBaseid()) return false;
       if (hasBaseid()) {
-        result = result && getBaseid()
-            .equals(other.getBaseid());
+        if (!getBaseid()
+            .equals(other.getBaseid())) return false;
       }
-      result = result && (hasAction() == other.hasAction());
+      if (hasAction() != other.hasAction()) return false;
       if (hasAction()) {
-        result = result && getAction()
-            .equals(other.getAction());
+        if (!getAction()
+            .equals(other.getAction())) return false;
       }
-      result = result && (hasMsg() == other.hasMsg());
+      if (hasMsg() != other.hasMsg()) return false;
       if (hasMsg()) {
-        result = result && getMsg()
-            .equals(other.getMsg());
-      }
-      result = result && getIdentitiesList()
-          .equals(other.getIdentitiesList());
-      result = result && getSignaturesList()
-          .equals(other.getSignaturesList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+        if (!getMsg()
+            .equals(other.getMsg())) return false;
+      }
+      if (!getIdentitiesList()
+          .equals(other.getIdentitiesList())) return false;
+      if (!getSignaturesList()
+          .equals(other.getSignaturesList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -10532,20 +10519,20 @@ public ch.epfl.dedis.lib.proto.DarcProto.Request buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.Request result = new ch.epfl.dedis.lib.proto.DarcProto.Request(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.baseid_ = baseid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.action_ = action_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.msg_ = msg_;
         if (identitiesBuilder_ == null) {
-          if (((bitField0_ & 0x00000008) == 0x00000008)) {
+          if (((bitField0_ & 0x00000008) != 0)) {
             identities_ = java.util.Collections.unmodifiableList(identities_);
             bitField0_ = (bitField0_ & ~0x00000008);
           }
@@ -10553,7 +10540,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Request buildPartial() {
         } else {
           result.identities_ = identitiesBuilder_.build();
         }
-        if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((bitField0_ & 0x00000010) != 0)) {
           signatures_ = java.util.Collections.unmodifiableList(signatures_);
           bitField0_ = (bitField0_ & ~0x00000010);
         }
@@ -10565,35 +10552,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.Request buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -10703,7 +10690,7 @@ public Builder mergeFrom(
        * required bytes baseid = 1;
        */
       public boolean hasBaseid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes baseid = 1;
@@ -10738,7 +10725,7 @@ public Builder clearBaseid() {
        * required string action = 2;
        */
       public boolean hasAction() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required string action = 2;
@@ -10814,7 +10801,7 @@ public Builder setActionBytes(
        * required bytes msg = 3;
        */
       public boolean hasMsg() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required bytes msg = 3;
@@ -10847,7 +10834,7 @@ public Builder clearMsg() {
       private java.util.List identities_ =
         java.util.Collections.emptyList();
       private void ensureIdentitiesIsMutable() {
-        if (!((bitField0_ & 0x00000008) == 0x00000008)) {
+        if (!((bitField0_ & 0x00000008) != 0)) {
           identities_ = new java.util.ArrayList(identities_);
           bitField0_ |= 0x00000008;
          }
@@ -11076,7 +11063,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Identity.Builder addIdentitiesBuilder(
           identitiesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.DarcProto.Identity, ch.epfl.dedis.lib.proto.DarcProto.Identity.Builder, ch.epfl.dedis.lib.proto.DarcProto.IdentityOrBuilder>(
                   identities_,
-                  ((bitField0_ & 0x00000008) == 0x00000008),
+                  ((bitField0_ & 0x00000008) != 0),
                   getParentForChildren(),
                   isClean());
           identities_ = null;
@@ -11086,7 +11073,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Identity.Builder addIdentitiesBuilder(
 
       private java.util.List signatures_ = java.util.Collections.emptyList();
       private void ensureSignaturesIsMutable() {
-        if (!((bitField0_ & 0x00000010) == 0x00000010)) {
+        if (!((bitField0_ & 0x00000010) != 0)) {
           signatures_ = new java.util.ArrayList(signatures_);
           bitField0_ |= 0x00000010;
          }
@@ -11096,7 +11083,8 @@ private void ensureSignaturesIsMutable() {
        */
       public java.util.List
           getSignaturesList() {
-        return java.util.Collections.unmodifiableList(signatures_);
+        return ((bitField0_ & 0x00000010) != 0) ?
+                 java.util.Collections.unmodifiableList(signatures_) : signatures_;
       }
       /**
        * repeated bytes signatures = 5;
@@ -11281,7 +11269,7 @@ private Rules(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 list_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -11304,7 +11292,7 @@ private Rules(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           list_ = java.util.Collections.unmodifiableList(list_);
         }
         this.unknownFields = unknownFields.build();
@@ -11410,11 +11398,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.Rules other = (ch.epfl.dedis.lib.proto.DarcProto.Rules) obj;
 
-      boolean result = true;
-      result = result && getListList()
-          .equals(other.getListList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getListList()
+          .equals(other.getListList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -11600,7 +11587,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Rules buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.Rules result = new ch.epfl.dedis.lib.proto.DarcProto.Rules(this);
         int from_bitField0_ = bitField0_;
         if (listBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             list_ = java.util.Collections.unmodifiableList(list_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -11614,35 +11601,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.Rules buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -11720,7 +11707,7 @@ public Builder mergeFrom(
       private java.util.List list_ =
         java.util.Collections.emptyList();
       private void ensureListIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           list_ = new java.util.ArrayList(list_);
           bitField0_ |= 0x00000001;
          }
@@ -11949,7 +11936,7 @@ public ch.epfl.dedis.lib.proto.DarcProto.Rule.Builder addListBuilder(
           listBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.DarcProto.Rule, ch.epfl.dedis.lib.proto.DarcProto.Rule.Builder, ch.epfl.dedis.lib.proto.DarcProto.RuleOrBuilder>(
                   list_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           list_ = null;
@@ -12131,7 +12118,7 @@ private Rule(
      * required string action = 1;
      */
     public boolean hasAction() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required string action = 1;
@@ -12173,7 +12160,7 @@ public java.lang.String getAction() {
      * required bytes expr = 2;
      */
     public boolean hasExpr() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes expr = 2;
@@ -12204,10 +12191,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, action_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, expr_);
       }
       unknownFields.writeTo(output);
@@ -12219,10 +12206,10 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, action_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, expr_);
       }
@@ -12241,19 +12228,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.DarcProto.Rule other = (ch.epfl.dedis.lib.proto.DarcProto.Rule) obj;
 
-      boolean result = true;
-      result = result && (hasAction() == other.hasAction());
+      if (hasAction() != other.hasAction()) return false;
       if (hasAction()) {
-        result = result && getAction()
-            .equals(other.getAction());
+        if (!getAction()
+            .equals(other.getAction())) return false;
       }
-      result = result && (hasExpr() == other.hasExpr());
+      if (hasExpr() != other.hasExpr()) return false;
       if (hasExpr()) {
-        result = result && getExpr()
-            .equals(other.getExpr());
+        if (!getExpr()
+            .equals(other.getExpr())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -12440,11 +12426,11 @@ public ch.epfl.dedis.lib.proto.DarcProto.Rule buildPartial() {
         ch.epfl.dedis.lib.proto.DarcProto.Rule result = new ch.epfl.dedis.lib.proto.DarcProto.Rule(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.action_ = action_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.expr_ = expr_;
@@ -12455,35 +12441,35 @@ public ch.epfl.dedis.lib.proto.DarcProto.Rule buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -12546,7 +12532,7 @@ public Builder mergeFrom(
        * required string action = 1;
        */
       public boolean hasAction() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required string action = 1;
@@ -12622,7 +12608,7 @@ public Builder setActionBytes(
        * required bytes expr = 2;
        */
       public boolean hasExpr() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes expr = 2;
diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/EventLogProto.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/EventLogProto.java
index 8c64807f84..5070cab9c6 100644
--- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/EventLogProto.java
+++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/EventLogProto.java
@@ -119,8 +119,6 @@ private SearchRequest() {
       instance_ = com.google.protobuf.ByteString.EMPTY;
       id_ = com.google.protobuf.ByteString.EMPTY;
       topic_ = "";
-      from_ = 0L;
-      to_ = 0L;
     }
 
     @java.lang.Override
@@ -212,7 +210,7 @@ private SearchRequest(
      * required bytes instance = 1;
      */
     public boolean hasInstance() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes instance = 1;
@@ -227,7 +225,7 @@ public com.google.protobuf.ByteString getInstance() {
      * required bytes id = 2;
      */
     public boolean hasId() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes id = 2;
@@ -246,7 +244,7 @@ public com.google.protobuf.ByteString getId() {
      * required string topic = 3;
      */
     public boolean hasTopic() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -300,7 +298,7 @@ public java.lang.String getTopic() {
      * required sint64 from = 4;
      */
     public boolean hasFrom() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * 
@@ -323,7 +321,7 @@ public long getFrom() {
      * required sint64 to = 5;
      */
     public boolean hasTo() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * 
@@ -370,19 +368,19 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, instance_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, id_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 3, topic_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeSInt64(4, from_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         output.writeSInt64(5, to_);
       }
       unknownFields.writeTo(output);
@@ -394,22 +392,22 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, instance_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, id_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, topic_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt64Size(4, from_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt64Size(5, to_);
       }
@@ -428,34 +426,33 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.EventLogProto.SearchRequest other = (ch.epfl.dedis.lib.proto.EventLogProto.SearchRequest) obj;
 
-      boolean result = true;
-      result = result && (hasInstance() == other.hasInstance());
+      if (hasInstance() != other.hasInstance()) return false;
       if (hasInstance()) {
-        result = result && getInstance()
-            .equals(other.getInstance());
+        if (!getInstance()
+            .equals(other.getInstance())) return false;
       }
-      result = result && (hasId() == other.hasId());
+      if (hasId() != other.hasId()) return false;
       if (hasId()) {
-        result = result && getId()
-            .equals(other.getId());
+        if (!getId()
+            .equals(other.getId())) return false;
       }
-      result = result && (hasTopic() == other.hasTopic());
+      if (hasTopic() != other.hasTopic()) return false;
       if (hasTopic()) {
-        result = result && getTopic()
-            .equals(other.getTopic());
+        if (!getTopic()
+            .equals(other.getTopic())) return false;
       }
-      result = result && (hasFrom() == other.hasFrom());
+      if (hasFrom() != other.hasFrom()) return false;
       if (hasFrom()) {
-        result = result && (getFrom()
-            == other.getFrom());
+        if (getFrom()
+            != other.getFrom()) return false;
       }
-      result = result && (hasTo() == other.hasTo());
+      if (hasTo() != other.hasTo()) return false;
       if (hasTo()) {
-        result = result && (getTo()
-            == other.getTo());
+        if (getTo()
+            != other.getTo()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -665,26 +662,26 @@ public ch.epfl.dedis.lib.proto.EventLogProto.SearchRequest buildPartial() {
         ch.epfl.dedis.lib.proto.EventLogProto.SearchRequest result = new ch.epfl.dedis.lib.proto.EventLogProto.SearchRequest(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.instance_ = instance_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.id_ = id_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.topic_ = topic_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          result.from_ = from_;
           to_bitField0_ |= 0x00000008;
         }
-        result.from_ = from_;
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((from_bitField0_ & 0x00000010) != 0)) {
+          result.to_ = to_;
           to_bitField0_ |= 0x00000010;
         }
-        result.to_ = to_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -692,35 +689,35 @@ public ch.epfl.dedis.lib.proto.EventLogProto.SearchRequest buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -801,7 +798,7 @@ public Builder mergeFrom(
        * required bytes instance = 1;
        */
       public boolean hasInstance() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes instance = 1;
@@ -836,7 +833,7 @@ public Builder clearInstance() {
        * required bytes id = 2;
        */
       public boolean hasId() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes id = 2;
@@ -875,7 +872,7 @@ public Builder clearId() {
        * required string topic = 3;
        */
       public boolean hasTopic() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -975,7 +972,7 @@ public Builder setTopicBytes(
        * required sint64 from = 4;
        */
       public boolean hasFrom() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * 
@@ -1023,7 +1020,7 @@ public Builder clearFrom() {
        * required sint64 to = 5;
        */
       public boolean hasTo() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return ((bitField0_ & 0x00000010) != 0);
       }
       /**
        * 
@@ -1181,7 +1178,6 @@ private SearchResponse(com.google.protobuf.GeneratedMessageV3.Builder builder
     }
     private SearchResponse() {
       events_ = java.util.Collections.emptyList();
-      truncated_ = false;
     }
 
     @java.lang.Override
@@ -1209,7 +1205,7 @@ private SearchResponse(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 events_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -1237,7 +1233,7 @@ private SearchResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           events_ = java.util.Collections.unmodifiableList(events_);
         }
         this.unknownFields = unknownFields.build();
@@ -1305,7 +1301,7 @@ public ch.epfl.dedis.lib.proto.EventLogProto.EventOrBuilder getEventsOrBuilder(
      * required bool truncated = 2;
      */
     public boolean hasTruncated() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -1347,7 +1343,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
       for (int i = 0; i < events_.size(); i++) {
         output.writeMessage(1, events_.get(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBool(2, truncated_);
       }
       unknownFields.writeTo(output);
@@ -1363,7 +1359,7 @@ public int getSerializedSize() {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, events_.get(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBoolSize(2, truncated_);
       }
@@ -1382,16 +1378,15 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.EventLogProto.SearchResponse other = (ch.epfl.dedis.lib.proto.EventLogProto.SearchResponse) obj;
 
-      boolean result = true;
-      result = result && getEventsList()
-          .equals(other.getEventsList());
-      result = result && (hasTruncated() == other.hasTruncated());
+      if (!getEventsList()
+          .equals(other.getEventsList())) return false;
+      if (hasTruncated() != other.hasTruncated()) return false;
       if (hasTruncated()) {
-        result = result && (getTruncated()
-            == other.getTruncated());
+        if (getTruncated()
+            != other.getTruncated()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -1585,7 +1580,7 @@ public ch.epfl.dedis.lib.proto.EventLogProto.SearchResponse buildPartial() {
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
         if (eventsBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             events_ = java.util.Collections.unmodifiableList(events_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -1593,10 +1588,10 @@ public ch.epfl.dedis.lib.proto.EventLogProto.SearchResponse buildPartial() {
         } else {
           result.events_ = eventsBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.truncated_ = truncated_;
           to_bitField0_ |= 0x00000001;
         }
-        result.truncated_ = truncated_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -1604,35 +1599,35 @@ public ch.epfl.dedis.lib.proto.EventLogProto.SearchResponse buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -1716,7 +1711,7 @@ public Builder mergeFrom(
       private java.util.List events_ =
         java.util.Collections.emptyList();
       private void ensureEventsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           events_ = new java.util.ArrayList(events_);
           bitField0_ |= 0x00000001;
          }
@@ -1945,7 +1940,7 @@ public ch.epfl.dedis.lib.proto.EventLogProto.Event.Builder addEventsBuilder(
           eventsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.EventLogProto.Event, ch.epfl.dedis.lib.proto.EventLogProto.Event.Builder, ch.epfl.dedis.lib.proto.EventLogProto.EventOrBuilder>(
                   events_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           events_ = null;
@@ -1964,7 +1959,7 @@ public ch.epfl.dedis.lib.proto.EventLogProto.Event.Builder addEventsBuilder(
        * required bool truncated = 2;
        */
       public boolean hasTruncated() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -2120,7 +2115,6 @@ private Event(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private Event() {
-      when_ = 0L;
       topic_ = "";
       content_ = "";
     }
@@ -2205,7 +2199,7 @@ private Event(
      * required sint64 when = 1;
      */
     public boolean hasWhen() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required sint64 when = 1;
@@ -2220,7 +2214,7 @@ public long getWhen() {
      * required string topic = 2;
      */
     public boolean hasTopic() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required string topic = 2;
@@ -2262,7 +2256,7 @@ public java.lang.String getTopic() {
      * required string content = 3;
      */
     public boolean hasContent() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required string content = 3;
@@ -2324,13 +2318,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt64(1, when_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 2, topic_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 3, content_);
       }
       unknownFields.writeTo(output);
@@ -2342,14 +2336,14 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt64Size(1, when_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, topic_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, content_);
       }
       size += unknownFields.getSerializedSize();
@@ -2367,24 +2361,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.EventLogProto.Event other = (ch.epfl.dedis.lib.proto.EventLogProto.Event) obj;
 
-      boolean result = true;
-      result = result && (hasWhen() == other.hasWhen());
+      if (hasWhen() != other.hasWhen()) return false;
       if (hasWhen()) {
-        result = result && (getWhen()
-            == other.getWhen());
+        if (getWhen()
+            != other.getWhen()) return false;
       }
-      result = result && (hasTopic() == other.hasTopic());
+      if (hasTopic() != other.hasTopic()) return false;
       if (hasTopic()) {
-        result = result && getTopic()
-            .equals(other.getTopic());
+        if (!getTopic()
+            .equals(other.getTopic())) return false;
       }
-      result = result && (hasContent() == other.hasContent());
+      if (hasContent() != other.hasContent()) return false;
       if (hasContent()) {
-        result = result && getContent()
-            .equals(other.getContent());
+        if (!getContent()
+            .equals(other.getContent())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -2579,15 +2572,15 @@ public ch.epfl.dedis.lib.proto.EventLogProto.Event buildPartial() {
         ch.epfl.dedis.lib.proto.EventLogProto.Event result = new ch.epfl.dedis.lib.proto.EventLogProto.Event(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.when_ = when_;
           to_bitField0_ |= 0x00000001;
         }
-        result.when_ = when_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.topic_ = topic_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.content_ = content_;
@@ -2598,35 +2591,35 @@ public ch.epfl.dedis.lib.proto.EventLogProto.Event buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -2697,7 +2690,7 @@ public Builder mergeFrom(
        * required sint64 when = 1;
        */
       public boolean hasWhen() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required sint64 when = 1;
@@ -2729,7 +2722,7 @@ public Builder clearWhen() {
        * required string topic = 2;
        */
       public boolean hasTopic() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required string topic = 2;
@@ -2805,7 +2798,7 @@ public Builder setTopicBytes(
        * required string content = 3;
        */
       public boolean hasContent() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required string content = 3;
diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/NetworkProto.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/NetworkProto.java
index 5861083b51..6141d7182d 100644
--- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/NetworkProto.java
+++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/NetworkProto.java
@@ -153,7 +153,7 @@ private ServerIdentity(
               break;
             }
             case 18: {
-              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
                 serviceIdentities_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000002;
               }
@@ -199,7 +199,7 @@ private ServerIdentity(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
           serviceIdentities_ = java.util.Collections.unmodifiableList(serviceIdentities_);
         }
         this.unknownFields = unknownFields.build();
@@ -226,7 +226,7 @@ private ServerIdentity(
      * required bytes public = 1;
      */
     public boolean hasPublic() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes public = 1;
@@ -276,7 +276,7 @@ public ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentityOrBuilder getServiceI
      * required bytes id = 3;
      */
     public boolean hasId() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes id = 3;
@@ -291,7 +291,7 @@ public com.google.protobuf.ByteString getId() {
      * required string address = 4;
      */
     public boolean hasAddress() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required string address = 4;
@@ -333,7 +333,7 @@ public java.lang.String getAddress() {
      * required string description = 5;
      */
     public boolean hasDescription() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * required string description = 5;
@@ -375,7 +375,7 @@ public java.lang.String getDescription() {
      * optional string url = 6;
      */
     public boolean hasUrl() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * optional string url = 6;
@@ -447,22 +447,22 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, public_);
       }
       for (int i = 0; i < serviceIdentities_.size(); i++) {
         output.writeMessage(2, serviceIdentities_.get(i));
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(3, id_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 4, address_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 5, description_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 6, url_);
       }
       unknownFields.writeTo(output);
@@ -474,7 +474,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, public_);
       }
@@ -482,17 +482,17 @@ public int getSerializedSize() {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, serviceIdentities_.get(i));
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, id_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, address_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, description_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, url_);
       }
       size += unknownFields.getSerializedSize();
@@ -510,36 +510,35 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity other = (ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity) obj;
 
-      boolean result = true;
-      result = result && (hasPublic() == other.hasPublic());
+      if (hasPublic() != other.hasPublic()) return false;
       if (hasPublic()) {
-        result = result && getPublic()
-            .equals(other.getPublic());
+        if (!getPublic()
+            .equals(other.getPublic())) return false;
       }
-      result = result && getServiceIdentitiesList()
-          .equals(other.getServiceIdentitiesList());
-      result = result && (hasId() == other.hasId());
+      if (!getServiceIdentitiesList()
+          .equals(other.getServiceIdentitiesList())) return false;
+      if (hasId() != other.hasId()) return false;
       if (hasId()) {
-        result = result && getId()
-            .equals(other.getId());
+        if (!getId()
+            .equals(other.getId())) return false;
       }
-      result = result && (hasAddress() == other.hasAddress());
+      if (hasAddress() != other.hasAddress()) return false;
       if (hasAddress()) {
-        result = result && getAddress()
-            .equals(other.getAddress());
+        if (!getAddress()
+            .equals(other.getAddress())) return false;
       }
-      result = result && (hasDescription() == other.hasDescription());
+      if (hasDescription() != other.hasDescription()) return false;
       if (hasDescription()) {
-        result = result && getDescription()
-            .equals(other.getDescription());
+        if (!getDescription()
+            .equals(other.getDescription())) return false;
       }
-      result = result && (hasUrl() == other.hasUrl());
+      if (hasUrl() != other.hasUrl()) return false;
       if (hasUrl()) {
-        result = result && getUrl()
-            .equals(other.getUrl());
+        if (!getUrl()
+            .equals(other.getUrl())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -751,12 +750,12 @@ public ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity buildPartial() {
         ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity result = new ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.public_ = public_;
         if (serviceIdentitiesBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          if (((bitField0_ & 0x00000002) != 0)) {
             serviceIdentities_ = java.util.Collections.unmodifiableList(serviceIdentities_);
             bitField0_ = (bitField0_ & ~0x00000002);
           }
@@ -764,19 +763,19 @@ public ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity buildPartial() {
         } else {
           result.serviceIdentities_ = serviceIdentitiesBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.id_ = id_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.address_ = address_;
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((from_bitField0_ & 0x00000010) != 0)) {
           to_bitField0_ |= 0x00000008;
         }
         result.description_ = description_;
-        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+        if (((from_bitField0_ & 0x00000020) != 0)) {
           to_bitField0_ |= 0x00000010;
         }
         result.url_ = url_;
@@ -787,35 +786,35 @@ public ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -928,7 +927,7 @@ public Builder mergeFrom(
        * required bytes public = 1;
        */
       public boolean hasPublic() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes public = 1;
@@ -961,7 +960,7 @@ public Builder clearPublic() {
       private java.util.List serviceIdentities_ =
         java.util.Collections.emptyList();
       private void ensureServiceIdentitiesIsMutable() {
-        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+        if (!((bitField0_ & 0x00000002) != 0)) {
           serviceIdentities_ = new java.util.ArrayList(serviceIdentities_);
           bitField0_ |= 0x00000002;
          }
@@ -1190,7 +1189,7 @@ public ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentity.Builder addServiceId
           serviceIdentitiesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentity, ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentity.Builder, ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentityOrBuilder>(
                   serviceIdentities_,
-                  ((bitField0_ & 0x00000002) == 0x00000002),
+                  ((bitField0_ & 0x00000002) != 0),
                   getParentForChildren(),
                   isClean());
           serviceIdentities_ = null;
@@ -1203,7 +1202,7 @@ public ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentity.Builder addServiceId
        * required bytes id = 3;
        */
       public boolean hasId() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required bytes id = 3;
@@ -1238,7 +1237,7 @@ public Builder clearId() {
        * required string address = 4;
        */
       public boolean hasAddress() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * required string address = 4;
@@ -1314,7 +1313,7 @@ public Builder setAddressBytes(
        * required string description = 5;
        */
       public boolean hasDescription() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return ((bitField0_ & 0x00000010) != 0);
       }
       /**
        * required string description = 5;
@@ -1390,7 +1389,7 @@ public Builder setDescriptionBytes(
        * optional string url = 6;
        */
       public boolean hasUrl() {
-        return ((bitField0_ & 0x00000020) == 0x00000020);
+        return ((bitField0_ & 0x00000020) != 0);
       }
       /**
        * optional string url = 6;
@@ -1652,7 +1651,7 @@ private ServiceIdentity(
      * required string name = 1;
      */
     public boolean hasName() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required string name = 1;
@@ -1694,7 +1693,7 @@ public java.lang.String getName() {
      * required string suite = 2;
      */
     public boolean hasSuite() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required string suite = 2;
@@ -1736,7 +1735,7 @@ public java.lang.String getSuite() {
      * required bytes public = 3;
      */
     public boolean hasPublic() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required bytes public = 3;
@@ -1771,13 +1770,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 2, suite_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, public_);
       }
       unknownFields.writeTo(output);
@@ -1789,13 +1788,13 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, suite_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, public_);
       }
@@ -1814,24 +1813,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentity other = (ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentity) obj;
 
-      boolean result = true;
-      result = result && (hasName() == other.hasName());
+      if (hasName() != other.hasName()) return false;
       if (hasName()) {
-        result = result && getName()
-            .equals(other.getName());
+        if (!getName()
+            .equals(other.getName())) return false;
       }
-      result = result && (hasSuite() == other.hasSuite());
+      if (hasSuite() != other.hasSuite()) return false;
       if (hasSuite()) {
-        result = result && getSuite()
-            .equals(other.getSuite());
+        if (!getSuite()
+            .equals(other.getSuite())) return false;
       }
-      result = result && (hasPublic() == other.hasPublic());
+      if (hasPublic() != other.hasPublic()) return false;
       if (hasPublic()) {
-        result = result && getPublic()
-            .equals(other.getPublic());
+        if (!getPublic()
+            .equals(other.getPublic())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -2020,15 +2018,15 @@ public ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentity buildPartial() {
         ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentity result = new ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentity(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.name_ = name_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.suite_ = suite_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.public_ = public_;
@@ -2039,35 +2037,35 @@ public ch.epfl.dedis.lib.proto.NetworkProto.ServiceIdentity buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -2138,7 +2136,7 @@ public Builder mergeFrom(
        * required string name = 1;
        */
       public boolean hasName() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required string name = 1;
@@ -2214,7 +2212,7 @@ public Builder setNameBytes(
        * required string suite = 2;
        */
       public boolean hasSuite() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required string suite = 2;
@@ -2290,7 +2288,7 @@ public Builder setSuiteBytes(
        * required bytes public = 3;
        */
       public boolean hasPublic() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required bytes public = 3;
diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/OnetProto.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/OnetProto.java
index 8d3ce10613..8d4638f74e 100644
--- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/OnetProto.java
+++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/OnetProto.java
@@ -108,7 +108,7 @@ private Roster(
               break;
             }
             case 18: {
-              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
                 list_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000002;
               }
@@ -136,7 +136,7 @@ private Roster(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
           list_ = java.util.Collections.unmodifiableList(list_);
         }
         this.unknownFields = unknownFields.build();
@@ -163,7 +163,7 @@ private Roster(
      * optional bytes id = 1;
      */
     public boolean hasId() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * optional bytes id = 1;
@@ -213,7 +213,7 @@ public ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentityOrBuilder getListOrBui
      * required bytes aggregate = 3;
      */
     public boolean hasAggregate() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes aggregate = 3;
@@ -246,13 +246,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, id_);
       }
       for (int i = 0; i < list_.size(); i++) {
         output.writeMessage(2, list_.get(i));
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(3, aggregate_);
       }
       unknownFields.writeTo(output);
@@ -264,7 +264,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, id_);
       }
@@ -272,7 +272,7 @@ public int getSerializedSize() {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, list_.get(i));
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, aggregate_);
       }
@@ -291,21 +291,20 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.OnetProto.Roster other = (ch.epfl.dedis.lib.proto.OnetProto.Roster) obj;
 
-      boolean result = true;
-      result = result && (hasId() == other.hasId());
+      if (hasId() != other.hasId()) return false;
       if (hasId()) {
-        result = result && getId()
-            .equals(other.getId());
+        if (!getId()
+            .equals(other.getId())) return false;
       }
-      result = result && getListList()
-          .equals(other.getListList());
-      result = result && (hasAggregate() == other.hasAggregate());
+      if (!getListList()
+          .equals(other.getListList())) return false;
+      if (hasAggregate() != other.hasAggregate()) return false;
       if (hasAggregate()) {
-        result = result && getAggregate()
-            .equals(other.getAggregate());
+        if (!getAggregate()
+            .equals(other.getAggregate())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -499,12 +498,12 @@ public ch.epfl.dedis.lib.proto.OnetProto.Roster buildPartial() {
         ch.epfl.dedis.lib.proto.OnetProto.Roster result = new ch.epfl.dedis.lib.proto.OnetProto.Roster(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.id_ = id_;
         if (listBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          if (((bitField0_ & 0x00000002) != 0)) {
             list_ = java.util.Collections.unmodifiableList(list_);
             bitField0_ = (bitField0_ & ~0x00000002);
           }
@@ -512,7 +511,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.Roster buildPartial() {
         } else {
           result.list_ = listBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.aggregate_ = aggregate_;
@@ -523,35 +522,35 @@ public ch.epfl.dedis.lib.proto.OnetProto.Roster buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -640,7 +639,7 @@ public Builder mergeFrom(
        * optional bytes id = 1;
        */
       public boolean hasId() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * optional bytes id = 1;
@@ -673,7 +672,7 @@ public Builder clearId() {
       private java.util.List list_ =
         java.util.Collections.emptyList();
       private void ensureListIsMutable() {
-        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+        if (!((bitField0_ & 0x00000002) != 0)) {
           list_ = new java.util.ArrayList(list_);
           bitField0_ |= 0x00000002;
          }
@@ -902,7 +901,7 @@ public ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity.Builder addListBuilde
           listBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity, ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity.Builder, ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentityOrBuilder>(
                   list_,
-                  ((bitField0_ & 0x00000002) == 0x00000002),
+                  ((bitField0_ & 0x00000002) != 0),
                   getParentForChildren(),
                   isClean());
           list_ = null;
@@ -915,7 +914,7 @@ public ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity.Builder addListBuilde
        * required bytes aggregate = 3;
        */
       public boolean hasAggregate() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required bytes aggregate = 3;
@@ -1075,7 +1074,7 @@ private Status(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 field_ = com.google.protobuf.MapField.newMapField(
                     FieldDefaultEntryHolder.defaultEntry);
                 mutable_bitField0_ |= 0x00000001;
@@ -1261,11 +1260,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.OnetProto.Status other = (ch.epfl.dedis.lib.proto.OnetProto.Status) obj;
 
-      boolean result = true;
-      result = result && internalGetField().equals(
-          other.internalGetField());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!internalGetField().equals(
+          other.internalGetField())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -1470,35 +1468,35 @@ public ch.epfl.dedis.lib.proto.OnetProto.Status buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/Personhood.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/Personhood.java
index 550cc26a83..df60ca4d07 100644
--- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/Personhood.java
+++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/Personhood.java
@@ -58,7 +58,6 @@ private PartyList(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private PartyList() {
-      wipeparties_ = false;
     }
 
     @java.lang.Override
@@ -87,7 +86,7 @@ private PartyList(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.Personhood.Party.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = newparty_.toBuilder();
               }
               newparty_ = input.readMessage(ch.epfl.dedis.lib.proto.Personhood.Party.parser(), extensionRegistry);
@@ -142,7 +141,7 @@ private PartyList(
      * optional .personhood.Party newparty = 1;
      */
     public boolean hasNewparty() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * optional .personhood.Party newparty = 1;
@@ -163,7 +162,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PartyOrBuilder getNewpartyOrBuilder()
      * optional bool wipeparties = 2;
      */
     public boolean hasWipeparties() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * optional bool wipeparties = 2;
@@ -192,10 +191,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getNewparty());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBool(2, wipeparties_);
       }
       unknownFields.writeTo(output);
@@ -207,11 +206,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getNewparty());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBoolSize(2, wipeparties_);
       }
@@ -230,19 +229,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.PartyList other = (ch.epfl.dedis.lib.proto.Personhood.PartyList) obj;
 
-      boolean result = true;
-      result = result && (hasNewparty() == other.hasNewparty());
+      if (hasNewparty() != other.hasNewparty()) return false;
       if (hasNewparty()) {
-        result = result && getNewparty()
-            .equals(other.getNewparty());
+        if (!getNewparty()
+            .equals(other.getNewparty())) return false;
       }
-      result = result && (hasWipeparties() == other.hasWipeparties());
+      if (hasWipeparties() != other.hasWipeparties()) return false;
       if (hasWipeparties()) {
-        result = result && (getWipeparties()
-            == other.getWipeparties());
+        if (getWipeparties()
+            != other.getWipeparties()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -436,18 +434,18 @@ public ch.epfl.dedis.lib.proto.Personhood.PartyList buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.PartyList result = new ch.epfl.dedis.lib.proto.Personhood.PartyList(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (newpartyBuilder_ == null) {
+            result.newparty_ = newparty_;
+          } else {
+            result.newparty_ = newpartyBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (newpartyBuilder_ == null) {
-          result.newparty_ = newparty_;
-        } else {
-          result.newparty_ = newpartyBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.wipeparties_ = wipeparties_;
           to_bitField0_ |= 0x00000002;
         }
-        result.wipeparties_ = wipeparties_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -455,35 +453,35 @@ public ch.epfl.dedis.lib.proto.Personhood.PartyList buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -538,14 +536,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.Personhood.Party newparty_ = null;
+      private ch.epfl.dedis.lib.proto.Personhood.Party newparty_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.Personhood.Party, ch.epfl.dedis.lib.proto.Personhood.Party.Builder, ch.epfl.dedis.lib.proto.Personhood.PartyOrBuilder> newpartyBuilder_;
       /**
        * optional .personhood.Party newparty = 1;
        */
       public boolean hasNewparty() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * optional .personhood.Party newparty = 1;
@@ -592,7 +590,7 @@ public Builder setNewparty(
        */
       public Builder mergeNewparty(ch.epfl.dedis.lib.proto.Personhood.Party value) {
         if (newpartyBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               newparty_ != null &&
               newparty_ != ch.epfl.dedis.lib.proto.Personhood.Party.getDefaultInstance()) {
             newparty_ =
@@ -661,7 +659,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PartyOrBuilder getNewpartyOrBuilder()
        * optional bool wipeparties = 2;
        */
       public boolean hasWipeparties() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * optional bool wipeparties = 2;
@@ -814,7 +812,7 @@ private PartyListResponse(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 parties_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -837,7 +835,7 @@ private PartyListResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           parties_ = java.util.Collections.unmodifiableList(parties_);
         }
         this.unknownFields = unknownFields.build();
@@ -943,11 +941,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.PartyListResponse other = (ch.epfl.dedis.lib.proto.Personhood.PartyListResponse) obj;
 
-      boolean result = true;
-      result = result && getPartiesList()
-          .equals(other.getPartiesList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getPartiesList()
+          .equals(other.getPartiesList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -1134,7 +1131,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PartyListResponse buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.PartyListResponse result = new ch.epfl.dedis.lib.proto.Personhood.PartyListResponse(this);
         int from_bitField0_ = bitField0_;
         if (partiesBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             parties_ = java.util.Collections.unmodifiableList(parties_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -1148,35 +1145,35 @@ public ch.epfl.dedis.lib.proto.Personhood.PartyListResponse buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -1254,7 +1251,7 @@ public Builder mergeFrom(
       private java.util.List parties_ =
         java.util.Collections.emptyList();
       private void ensurePartiesIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           parties_ = new java.util.ArrayList(parties_);
           bitField0_ |= 0x00000001;
          }
@@ -1483,7 +1480,7 @@ public ch.epfl.dedis.lib.proto.Personhood.Party.Builder addPartiesBuilder(
           partiesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.Personhood.Party, ch.epfl.dedis.lib.proto.Personhood.Party.Builder, ch.epfl.dedis.lib.proto.Personhood.PartyOrBuilder>(
                   parties_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           parties_ = null;
@@ -1653,7 +1650,7 @@ private Party(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = roster_.toBuilder();
               }
               roster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry);
@@ -1717,7 +1714,7 @@ private Party(
      * required .onet.Roster roster = 1;
      */
     public boolean hasRoster() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -1750,7 +1747,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() {
      * required bytes byzcoinid = 2;
      */
     public boolean hasByzcoinid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -1773,7 +1770,7 @@ public com.google.protobuf.ByteString getByzcoinid() {
      * required bytes instanceid = 3;
      */
     public boolean hasInstanceid() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -1816,13 +1813,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getRoster());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, instanceid_);
       }
       unknownFields.writeTo(output);
@@ -1834,15 +1831,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getRoster());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, instanceid_);
       }
@@ -1861,24 +1858,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.Party other = (ch.epfl.dedis.lib.proto.Personhood.Party) obj;
 
-      boolean result = true;
-      result = result && (hasRoster() == other.hasRoster());
+      if (hasRoster() != other.hasRoster()) return false;
       if (hasRoster()) {
-        result = result && getRoster()
-            .equals(other.getRoster());
+        if (!getRoster()
+            .equals(other.getRoster())) return false;
       }
-      result = result && (hasByzcoinid() == other.hasByzcoinid());
+      if (hasByzcoinid() != other.hasByzcoinid()) return false;
       if (hasByzcoinid()) {
-        result = result && getByzcoinid()
-            .equals(other.getByzcoinid());
+        if (!getByzcoinid()
+            .equals(other.getByzcoinid())) return false;
       }
-      result = result && (hasInstanceid() == other.hasInstanceid());
+      if (hasInstanceid() != other.hasInstanceid()) return false;
       if (hasInstanceid()) {
-        result = result && getInstanceid()
-            .equals(other.getInstanceid());
+        if (!getInstanceid()
+            .equals(other.getInstanceid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -2076,19 +2072,19 @@ public ch.epfl.dedis.lib.proto.Personhood.Party buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.Party result = new ch.epfl.dedis.lib.proto.Personhood.Party(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (rosterBuilder_ == null) {
+            result.roster_ = roster_;
+          } else {
+            result.roster_ = rosterBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (rosterBuilder_ == null) {
-          result.roster_ = roster_;
-        } else {
-          result.roster_ = rosterBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.byzcoinid_ = byzcoinid_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.instanceid_ = instanceid_;
@@ -2099,35 +2095,35 @@ public ch.epfl.dedis.lib.proto.Personhood.Party buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -2192,7 +2188,7 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_ = null;
+      private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> rosterBuilder_;
       /**
@@ -2203,7 +2199,7 @@ public Builder mergeFrom(
        * required .onet.Roster roster = 1;
        */
       public boolean hasRoster() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -2266,7 +2262,7 @@ public Builder setRoster(
        */
       public Builder mergeRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) {
         if (rosterBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               roster_ != null &&
               roster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) {
             roster_ =
@@ -2355,7 +2351,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() {
        * required bytes byzcoinid = 2;
        */
       public boolean hasByzcoinid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -2406,7 +2402,7 @@ public Builder clearByzcoinid() {
        * required bytes instanceid = 3;
        */
       public boolean hasInstanceid() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -2544,7 +2540,6 @@ private RoPaSciList(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private RoPaSciList() {
-      wipe_ = false;
     }
 
     @java.lang.Override
@@ -2573,7 +2568,7 @@ private RoPaSciList(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.Personhood.RoPaSci.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = newropasci_.toBuilder();
               }
               newropasci_ = input.readMessage(ch.epfl.dedis.lib.proto.Personhood.RoPaSci.parser(), extensionRegistry);
@@ -2628,7 +2623,7 @@ private RoPaSciList(
      * optional .personhood.RoPaSci newropasci = 1;
      */
     public boolean hasNewropasci() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * optional .personhood.RoPaSci newropasci = 1;
@@ -2649,7 +2644,7 @@ public ch.epfl.dedis.lib.proto.Personhood.RoPaSciOrBuilder getNewropasciOrBuilde
      * optional bool wipe = 2;
      */
     public boolean hasWipe() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * optional bool wipe = 2;
@@ -2678,10 +2673,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getNewropasci());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBool(2, wipe_);
       }
       unknownFields.writeTo(output);
@@ -2693,11 +2688,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getNewropasci());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBoolSize(2, wipe_);
       }
@@ -2716,19 +2711,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.RoPaSciList other = (ch.epfl.dedis.lib.proto.Personhood.RoPaSciList) obj;
 
-      boolean result = true;
-      result = result && (hasNewropasci() == other.hasNewropasci());
+      if (hasNewropasci() != other.hasNewropasci()) return false;
       if (hasNewropasci()) {
-        result = result && getNewropasci()
-            .equals(other.getNewropasci());
+        if (!getNewropasci()
+            .equals(other.getNewropasci())) return false;
       }
-      result = result && (hasWipe() == other.hasWipe());
+      if (hasWipe() != other.hasWipe()) return false;
       if (hasWipe()) {
-        result = result && (getWipe()
-            == other.getWipe());
+        if (getWipe()
+            != other.getWipe()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -2922,18 +2916,18 @@ public ch.epfl.dedis.lib.proto.Personhood.RoPaSciList buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.RoPaSciList result = new ch.epfl.dedis.lib.proto.Personhood.RoPaSciList(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (newropasciBuilder_ == null) {
+            result.newropasci_ = newropasci_;
+          } else {
+            result.newropasci_ = newropasciBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (newropasciBuilder_ == null) {
-          result.newropasci_ = newropasci_;
-        } else {
-          result.newropasci_ = newropasciBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.wipe_ = wipe_;
           to_bitField0_ |= 0x00000002;
         }
-        result.wipe_ = wipe_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -2941,35 +2935,35 @@ public ch.epfl.dedis.lib.proto.Personhood.RoPaSciList buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -3024,14 +3018,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.Personhood.RoPaSci newropasci_ = null;
+      private ch.epfl.dedis.lib.proto.Personhood.RoPaSci newropasci_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.Personhood.RoPaSci, ch.epfl.dedis.lib.proto.Personhood.RoPaSci.Builder, ch.epfl.dedis.lib.proto.Personhood.RoPaSciOrBuilder> newropasciBuilder_;
       /**
        * optional .personhood.RoPaSci newropasci = 1;
        */
       public boolean hasNewropasci() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * optional .personhood.RoPaSci newropasci = 1;
@@ -3078,7 +3072,7 @@ public Builder setNewropasci(
        */
       public Builder mergeNewropasci(ch.epfl.dedis.lib.proto.Personhood.RoPaSci value) {
         if (newropasciBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               newropasci_ != null &&
               newropasci_ != ch.epfl.dedis.lib.proto.Personhood.RoPaSci.getDefaultInstance()) {
             newropasci_ =
@@ -3147,7 +3141,7 @@ public ch.epfl.dedis.lib.proto.Personhood.RoPaSciOrBuilder getNewropasciOrBuilde
        * optional bool wipe = 2;
        */
       public boolean hasWipe() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * optional bool wipe = 2;
@@ -3300,7 +3294,7 @@ private RoPaSciListResponse(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 ropascis_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -3323,7 +3317,7 @@ private RoPaSciListResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           ropascis_ = java.util.Collections.unmodifiableList(ropascis_);
         }
         this.unknownFields = unknownFields.build();
@@ -3429,11 +3423,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.RoPaSciListResponse other = (ch.epfl.dedis.lib.proto.Personhood.RoPaSciListResponse) obj;
 
-      boolean result = true;
-      result = result && getRopascisList()
-          .equals(other.getRopascisList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getRopascisList()
+          .equals(other.getRopascisList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -3620,7 +3613,7 @@ public ch.epfl.dedis.lib.proto.Personhood.RoPaSciListResponse buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.RoPaSciListResponse result = new ch.epfl.dedis.lib.proto.Personhood.RoPaSciListResponse(this);
         int from_bitField0_ = bitField0_;
         if (ropascisBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             ropascis_ = java.util.Collections.unmodifiableList(ropascis_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -3634,35 +3627,35 @@ public ch.epfl.dedis.lib.proto.Personhood.RoPaSciListResponse buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -3740,7 +3733,7 @@ public Builder mergeFrom(
       private java.util.List ropascis_ =
         java.util.Collections.emptyList();
       private void ensureRopascisIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           ropascis_ = new java.util.ArrayList(ropascis_);
           bitField0_ |= 0x00000001;
          }
@@ -3969,7 +3962,7 @@ public ch.epfl.dedis.lib.proto.Personhood.RoPaSci.Builder addRopascisBuilder(
           ropascisBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.Personhood.RoPaSci, ch.epfl.dedis.lib.proto.Personhood.RoPaSci.Builder, ch.epfl.dedis.lib.proto.Personhood.RoPaSciOrBuilder>(
                   ropascis_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           ropascis_ = null;
@@ -4145,7 +4138,7 @@ private RoPaSci(
      * required bytes byzcoinid = 1;
      */
     public boolean hasByzcoinid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes byzcoinid = 1;
@@ -4160,7 +4153,7 @@ public com.google.protobuf.ByteString getByzcoinid() {
      * required bytes ropasciid = 2;
      */
     public boolean hasRopasciid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes ropasciid = 2;
@@ -4191,10 +4184,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, ropasciid_);
       }
       unknownFields.writeTo(output);
@@ -4206,11 +4199,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, ropasciid_);
       }
@@ -4229,19 +4222,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.RoPaSci other = (ch.epfl.dedis.lib.proto.Personhood.RoPaSci) obj;
 
-      boolean result = true;
-      result = result && (hasByzcoinid() == other.hasByzcoinid());
+      if (hasByzcoinid() != other.hasByzcoinid()) return false;
       if (hasByzcoinid()) {
-        result = result && getByzcoinid()
-            .equals(other.getByzcoinid());
+        if (!getByzcoinid()
+            .equals(other.getByzcoinid())) return false;
       }
-      result = result && (hasRopasciid() == other.hasRopasciid());
+      if (hasRopasciid() != other.hasRopasciid()) return false;
       if (hasRopasciid()) {
-        result = result && getRopasciid()
-            .equals(other.getRopasciid());
+        if (!getRopasciid()
+            .equals(other.getRopasciid())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -4428,11 +4420,11 @@ public ch.epfl.dedis.lib.proto.Personhood.RoPaSci buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.RoPaSci result = new ch.epfl.dedis.lib.proto.Personhood.RoPaSci(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.byzcoinid_ = byzcoinid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.ropasciid_ = ropasciid_;
@@ -4443,35 +4435,35 @@ public ch.epfl.dedis.lib.proto.Personhood.RoPaSci buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -4532,7 +4524,7 @@ public Builder mergeFrom(
        * required bytes byzcoinid = 1;
        */
       public boolean hasByzcoinid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes byzcoinid = 1;
@@ -4567,7 +4559,7 @@ public Builder clearByzcoinid() {
        * required bytes ropasciid = 2;
        */
       public boolean hasRopasciid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes ropasciid = 2;
@@ -4757,7 +4749,7 @@ private StringReply(
      * required string reply = 1;
      */
     public boolean hasReply() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required string reply = 1;
@@ -4811,7 +4803,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, reply_);
       }
       unknownFields.writeTo(output);
@@ -4823,7 +4815,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, reply_);
       }
       size += unknownFields.getSerializedSize();
@@ -4841,14 +4833,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.StringReply other = (ch.epfl.dedis.lib.proto.Personhood.StringReply) obj;
 
-      boolean result = true;
-      result = result && (hasReply() == other.hasReply());
+      if (hasReply() != other.hasReply()) return false;
       if (hasReply()) {
-        result = result && getReply()
-            .equals(other.getReply());
+        if (!getReply()
+            .equals(other.getReply())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -5030,7 +5021,7 @@ public ch.epfl.dedis.lib.proto.Personhood.StringReply buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.StringReply result = new ch.epfl.dedis.lib.proto.Personhood.StringReply(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.reply_ = reply_;
@@ -5041,35 +5032,35 @@ public ch.epfl.dedis.lib.proto.Personhood.StringReply buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -5126,7 +5117,7 @@ public Builder mergeFrom(
        * required string reply = 1;
        */
       public boolean hasReply() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required string reply = 1;
@@ -5335,8 +5326,6 @@ private RoPaSciStruct(com.google.protobuf.GeneratedMessageV3.Builder builder)
     private RoPaSciStruct() {
       description_ = "";
       firstplayerhash_ = com.google.protobuf.ByteString.EMPTY;
-      firstplayer_ = 0;
-      secondplayer_ = 0;
       secondplayeraccount_ = com.google.protobuf.ByteString.EMPTY;
     }
 
@@ -5372,7 +5361,7 @@ private RoPaSciStruct(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = stake_.toBuilder();
               }
               stake_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.parser(), extensionRegistry);
@@ -5442,7 +5431,7 @@ private RoPaSciStruct(
      * required string description = 1;
      */
     public boolean hasDescription() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required string description = 1;
@@ -5484,7 +5473,7 @@ public java.lang.String getDescription() {
      * required .byzcoin.Coin stake = 2;
      */
     public boolean hasStake() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required .byzcoin.Coin stake = 2;
@@ -5505,7 +5494,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder getStakeOrBuilder() {
      * required bytes firstplayerhash = 3;
      */
     public boolean hasFirstplayerhash() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required bytes firstplayerhash = 3;
@@ -5520,7 +5509,7 @@ public com.google.protobuf.ByteString getFirstplayerhash() {
      * optional sint32 firstplayer = 4;
      */
     public boolean hasFirstplayer() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * optional sint32 firstplayer = 4;
@@ -5535,7 +5524,7 @@ public int getFirstplayer() {
      * optional sint32 secondplayer = 5;
      */
     public boolean hasSecondplayer() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * optional sint32 secondplayer = 5;
@@ -5550,7 +5539,7 @@ public int getSecondplayer() {
      * optional bytes secondplayeraccount = 6;
      */
     public boolean hasSecondplayeraccount() {
-      return ((bitField0_ & 0x00000020) == 0x00000020);
+      return ((bitField0_ & 0x00000020) != 0);
     }
     /**
      * optional bytes secondplayeraccount = 6;
@@ -5589,22 +5578,22 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, description_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getStake());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, firstplayerhash_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeSInt32(4, firstplayer_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         output.writeSInt32(5, secondplayer_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         output.writeBytes(6, secondplayeraccount_);
       }
       unknownFields.writeTo(output);
@@ -5616,26 +5605,26 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, description_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getStake());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, firstplayerhash_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(4, firstplayer_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(5, secondplayer_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(6, secondplayeraccount_);
       }
@@ -5654,39 +5643,38 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.RoPaSciStruct other = (ch.epfl.dedis.lib.proto.Personhood.RoPaSciStruct) obj;
 
-      boolean result = true;
-      result = result && (hasDescription() == other.hasDescription());
+      if (hasDescription() != other.hasDescription()) return false;
       if (hasDescription()) {
-        result = result && getDescription()
-            .equals(other.getDescription());
+        if (!getDescription()
+            .equals(other.getDescription())) return false;
       }
-      result = result && (hasStake() == other.hasStake());
+      if (hasStake() != other.hasStake()) return false;
       if (hasStake()) {
-        result = result && getStake()
-            .equals(other.getStake());
+        if (!getStake()
+            .equals(other.getStake())) return false;
       }
-      result = result && (hasFirstplayerhash() == other.hasFirstplayerhash());
+      if (hasFirstplayerhash() != other.hasFirstplayerhash()) return false;
       if (hasFirstplayerhash()) {
-        result = result && getFirstplayerhash()
-            .equals(other.getFirstplayerhash());
+        if (!getFirstplayerhash()
+            .equals(other.getFirstplayerhash())) return false;
       }
-      result = result && (hasFirstplayer() == other.hasFirstplayer());
+      if (hasFirstplayer() != other.hasFirstplayer()) return false;
       if (hasFirstplayer()) {
-        result = result && (getFirstplayer()
-            == other.getFirstplayer());
+        if (getFirstplayer()
+            != other.getFirstplayer()) return false;
       }
-      result = result && (hasSecondplayer() == other.hasSecondplayer());
+      if (hasSecondplayer() != other.hasSecondplayer()) return false;
       if (hasSecondplayer()) {
-        result = result && (getSecondplayer()
-            == other.getSecondplayer());
+        if (getSecondplayer()
+            != other.getSecondplayer()) return false;
       }
-      result = result && (hasSecondplayeraccount() == other.hasSecondplayeraccount());
+      if (hasSecondplayeraccount() != other.hasSecondplayeraccount()) return false;
       if (hasSecondplayeraccount()) {
-        result = result && getSecondplayeraccount()
-            .equals(other.getSecondplayeraccount());
+        if (!getSecondplayeraccount()
+            .equals(other.getSecondplayeraccount())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -5902,31 +5890,31 @@ public ch.epfl.dedis.lib.proto.Personhood.RoPaSciStruct buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.RoPaSciStruct result = new ch.epfl.dedis.lib.proto.Personhood.RoPaSciStruct(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.description_ = description_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (stakeBuilder_ == null) {
+            result.stake_ = stake_;
+          } else {
+            result.stake_ = stakeBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (stakeBuilder_ == null) {
-          result.stake_ = stake_;
-        } else {
-          result.stake_ = stakeBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.firstplayerhash_ = firstplayerhash_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          result.firstplayer_ = firstplayer_;
           to_bitField0_ |= 0x00000008;
         }
-        result.firstplayer_ = firstplayer_;
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((from_bitField0_ & 0x00000010) != 0)) {
+          result.secondplayer_ = secondplayer_;
           to_bitField0_ |= 0x00000010;
         }
-        result.secondplayer_ = secondplayer_;
-        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+        if (((from_bitField0_ & 0x00000020) != 0)) {
           to_bitField0_ |= 0x00000020;
         }
         result.secondplayeraccount_ = secondplayeraccount_;
@@ -5937,35 +5925,35 @@ public ch.epfl.dedis.lib.proto.Personhood.RoPaSciStruct buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -6046,7 +6034,7 @@ public Builder mergeFrom(
        * required string description = 1;
        */
       public boolean hasDescription() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required string description = 1;
@@ -6117,14 +6105,14 @@ public Builder setDescriptionBytes(
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin stake_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin stake_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Coin, ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder> stakeBuilder_;
       /**
        * required .byzcoin.Coin stake = 2;
        */
       public boolean hasStake() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required .byzcoin.Coin stake = 2;
@@ -6171,7 +6159,7 @@ public Builder setStake(
        */
       public Builder mergeStake(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin value) {
         if (stakeBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               stake_ != null &&
               stake_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.getDefaultInstance()) {
             stake_ =
@@ -6240,7 +6228,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder getStakeOrBuilder() {
        * required bytes firstplayerhash = 3;
        */
       public boolean hasFirstplayerhash() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required bytes firstplayerhash = 3;
@@ -6275,7 +6263,7 @@ public Builder clearFirstplayerhash() {
        * optional sint32 firstplayer = 4;
        */
       public boolean hasFirstplayer() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * optional sint32 firstplayer = 4;
@@ -6307,7 +6295,7 @@ public Builder clearFirstplayer() {
        * optional sint32 secondplayer = 5;
        */
       public boolean hasSecondplayer() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return ((bitField0_ & 0x00000010) != 0);
       }
       /**
        * optional sint32 secondplayer = 5;
@@ -6339,7 +6327,7 @@ public Builder clearSecondplayer() {
        * optional bytes secondplayeraccount = 6;
        */
       public boolean hasSecondplayeraccount() {
-        return ((bitField0_ & 0x00000020) == 0x00000020);
+        return ((bitField0_ & 0x00000020) != 0);
       }
       /**
        * optional bytes secondplayeraccount = 6;
@@ -6494,7 +6482,7 @@ private CredentialStruct(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 credentials_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -6517,7 +6505,7 @@ private CredentialStruct(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           credentials_ = java.util.Collections.unmodifiableList(credentials_);
         }
         this.unknownFields = unknownFields.build();
@@ -6623,11 +6611,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.CredentialStruct other = (ch.epfl.dedis.lib.proto.Personhood.CredentialStruct) obj;
 
-      boolean result = true;
-      result = result && getCredentialsList()
-          .equals(other.getCredentialsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getCredentialsList()
+          .equals(other.getCredentialsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -6813,7 +6800,7 @@ public ch.epfl.dedis.lib.proto.Personhood.CredentialStruct buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.CredentialStruct result = new ch.epfl.dedis.lib.proto.Personhood.CredentialStruct(this);
         int from_bitField0_ = bitField0_;
         if (credentialsBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             credentials_ = java.util.Collections.unmodifiableList(credentials_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -6827,35 +6814,35 @@ public ch.epfl.dedis.lib.proto.Personhood.CredentialStruct buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -6933,7 +6920,7 @@ public Builder mergeFrom(
       private java.util.List credentials_ =
         java.util.Collections.emptyList();
       private void ensureCredentialsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           credentials_ = new java.util.ArrayList(credentials_);
           bitField0_ |= 0x00000001;
          }
@@ -7162,7 +7149,7 @@ public ch.epfl.dedis.lib.proto.Personhood.Credential.Builder addCredentialsBuild
           credentialsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.Personhood.Credential, ch.epfl.dedis.lib.proto.Personhood.Credential.Builder, ch.epfl.dedis.lib.proto.Personhood.CredentialOrBuilder>(
                   credentials_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           credentials_ = null;
@@ -7316,7 +7303,7 @@ private Credential(
               break;
             }
             case 18: {
-              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
                 attributes_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000002;
               }
@@ -7339,7 +7326,7 @@ private Credential(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
           attributes_ = java.util.Collections.unmodifiableList(attributes_);
         }
         this.unknownFields = unknownFields.build();
@@ -7366,7 +7353,7 @@ private Credential(
      * required string name = 1;
      */
     public boolean hasName() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required string name = 1;
@@ -7461,7 +7448,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
       }
       for (int i = 0; i < attributes_.size(); i++) {
@@ -7476,7 +7463,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
       }
       for (int i = 0; i < attributes_.size(); i++) {
@@ -7498,16 +7485,15 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.Credential other = (ch.epfl.dedis.lib.proto.Personhood.Credential) obj;
 
-      boolean result = true;
-      result = result && (hasName() == other.hasName());
+      if (hasName() != other.hasName()) return false;
       if (hasName()) {
-        result = result && getName()
-            .equals(other.getName());
+        if (!getName()
+            .equals(other.getName())) return false;
       }
-      result = result && getAttributesList()
-          .equals(other.getAttributesList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getAttributesList()
+          .equals(other.getAttributesList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -7699,12 +7685,12 @@ public ch.epfl.dedis.lib.proto.Personhood.Credential buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.Credential result = new ch.epfl.dedis.lib.proto.Personhood.Credential(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.name_ = name_;
         if (attributesBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          if (((bitField0_ & 0x00000002) != 0)) {
             attributes_ = java.util.Collections.unmodifiableList(attributes_);
             bitField0_ = (bitField0_ & ~0x00000002);
           }
@@ -7719,35 +7705,35 @@ public ch.epfl.dedis.lib.proto.Personhood.Credential buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -7835,7 +7821,7 @@ public Builder mergeFrom(
        * required string name = 1;
        */
       public boolean hasName() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required string name = 1;
@@ -7909,7 +7895,7 @@ public Builder setNameBytes(
       private java.util.List attributes_ =
         java.util.Collections.emptyList();
       private void ensureAttributesIsMutable() {
-        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+        if (!((bitField0_ & 0x00000002) != 0)) {
           attributes_ = new java.util.ArrayList(attributes_);
           bitField0_ |= 0x00000002;
          }
@@ -8138,7 +8124,7 @@ public ch.epfl.dedis.lib.proto.Personhood.Attribute.Builder addAttributesBuilder
           attributesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.Personhood.Attribute, ch.epfl.dedis.lib.proto.Personhood.Attribute.Builder, ch.epfl.dedis.lib.proto.Personhood.AttributeOrBuilder>(
                   attributes_,
-                  ((bitField0_ & 0x00000002) == 0x00000002),
+                  ((bitField0_ & 0x00000002) != 0),
                   getParentForChildren(),
                   isClean());
           attributes_ = null;
@@ -8320,7 +8306,7 @@ private Attribute(
      * required string name = 1;
      */
     public boolean hasName() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required string name = 1;
@@ -8362,7 +8348,7 @@ public java.lang.String getName() {
      * required bytes value = 2;
      */
     public boolean hasValue() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes value = 2;
@@ -8393,10 +8379,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, value_);
       }
       unknownFields.writeTo(output);
@@ -8408,10 +8394,10 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, value_);
       }
@@ -8430,19 +8416,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.Attribute other = (ch.epfl.dedis.lib.proto.Personhood.Attribute) obj;
 
-      boolean result = true;
-      result = result && (hasName() == other.hasName());
+      if (hasName() != other.hasName()) return false;
       if (hasName()) {
-        result = result && getName()
-            .equals(other.getName());
+        if (!getName()
+            .equals(other.getName())) return false;
       }
-      result = result && (hasValue() == other.hasValue());
+      if (hasValue() != other.hasValue()) return false;
       if (hasValue()) {
-        result = result && getValue()
-            .equals(other.getValue());
+        if (!getValue()
+            .equals(other.getValue())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -8629,11 +8614,11 @@ public ch.epfl.dedis.lib.proto.Personhood.Attribute buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.Attribute result = new ch.epfl.dedis.lib.proto.Personhood.Attribute(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.name_ = name_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.value_ = value_;
@@ -8644,35 +8629,35 @@ public ch.epfl.dedis.lib.proto.Personhood.Attribute buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -8735,7 +8720,7 @@ public Builder mergeFrom(
        * required string name = 1;
        */
       public boolean hasName() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required string name = 1;
@@ -8811,7 +8796,7 @@ public Builder setNameBytes(
        * required bytes value = 2;
        */
       public boolean hasValue() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes value = 2;
@@ -9018,7 +9003,7 @@ private SpawnerStruct(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = costdarc_.toBuilder();
               }
               costdarc_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.parser(), extensionRegistry);
@@ -9031,7 +9016,7 @@ private SpawnerStruct(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = costcoin_.toBuilder();
               }
               costcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.parser(), extensionRegistry);
@@ -9044,7 +9029,7 @@ private SpawnerStruct(
             }
             case 26: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (((bitField0_ & 0x00000004) != 0)) {
                 subBuilder = costcredential_.toBuilder();
               }
               costcredential_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.parser(), extensionRegistry);
@@ -9057,7 +9042,7 @@ private SpawnerStruct(
             }
             case 34: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000008) == 0x00000008)) {
+              if (((bitField0_ & 0x00000008) != 0)) {
                 subBuilder = costparty_.toBuilder();
               }
               costparty_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.parser(), extensionRegistry);
@@ -9075,7 +9060,7 @@ private SpawnerStruct(
             }
             case 50: {
               ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000020) == 0x00000020)) {
+              if (((bitField0_ & 0x00000020) != 0)) {
                 subBuilder = costropasci_.toBuilder();
               }
               costropasci_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.parser(), extensionRegistry);
@@ -9125,7 +9110,7 @@ private SpawnerStruct(
      * required .byzcoin.Coin costdarc = 1;
      */
     public boolean hasCostdarc() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required .byzcoin.Coin costdarc = 1;
@@ -9146,7 +9131,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder getCostdarcOrBuilder()
      * required .byzcoin.Coin costcoin = 2;
      */
     public boolean hasCostcoin() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required .byzcoin.Coin costcoin = 2;
@@ -9167,7 +9152,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder getCostcoinOrBuilder()
      * required .byzcoin.Coin costcredential = 3;
      */
     public boolean hasCostcredential() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required .byzcoin.Coin costcredential = 3;
@@ -9188,7 +9173,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder getCostcredentialOrBui
      * required .byzcoin.Coin costparty = 4;
      */
     public boolean hasCostparty() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * required .byzcoin.Coin costparty = 4;
@@ -9209,7 +9194,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder getCostpartyOrBuilder(
      * required bytes beneficiary = 5;
      */
     public boolean hasBeneficiary() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * required bytes beneficiary = 5;
@@ -9224,7 +9209,7 @@ public com.google.protobuf.ByteString getBeneficiary() {
      * optional .byzcoin.Coin costropasci = 6;
      */
     public boolean hasCostropasci() {
-      return ((bitField0_ & 0x00000020) == 0x00000020);
+      return ((bitField0_ & 0x00000020) != 0);
     }
     /**
      * optional .byzcoin.Coin costropasci = 6;
@@ -9295,22 +9280,22 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getCostdarc());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getCostcoin());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeMessage(3, getCostcredential());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeMessage(4, getCostparty());
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         output.writeBytes(5, beneficiary_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         output.writeMessage(6, getCostropasci());
       }
       unknownFields.writeTo(output);
@@ -9322,27 +9307,27 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getCostdarc());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getCostcoin());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getCostcredential());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(4, getCostparty());
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(5, beneficiary_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(6, getCostropasci());
       }
@@ -9361,39 +9346,38 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.SpawnerStruct other = (ch.epfl.dedis.lib.proto.Personhood.SpawnerStruct) obj;
 
-      boolean result = true;
-      result = result && (hasCostdarc() == other.hasCostdarc());
+      if (hasCostdarc() != other.hasCostdarc()) return false;
       if (hasCostdarc()) {
-        result = result && getCostdarc()
-            .equals(other.getCostdarc());
+        if (!getCostdarc()
+            .equals(other.getCostdarc())) return false;
       }
-      result = result && (hasCostcoin() == other.hasCostcoin());
+      if (hasCostcoin() != other.hasCostcoin()) return false;
       if (hasCostcoin()) {
-        result = result && getCostcoin()
-            .equals(other.getCostcoin());
+        if (!getCostcoin()
+            .equals(other.getCostcoin())) return false;
       }
-      result = result && (hasCostcredential() == other.hasCostcredential());
+      if (hasCostcredential() != other.hasCostcredential()) return false;
       if (hasCostcredential()) {
-        result = result && getCostcredential()
-            .equals(other.getCostcredential());
+        if (!getCostcredential()
+            .equals(other.getCostcredential())) return false;
       }
-      result = result && (hasCostparty() == other.hasCostparty());
+      if (hasCostparty() != other.hasCostparty()) return false;
       if (hasCostparty()) {
-        result = result && getCostparty()
-            .equals(other.getCostparty());
+        if (!getCostparty()
+            .equals(other.getCostparty())) return false;
       }
-      result = result && (hasBeneficiary() == other.hasBeneficiary());
+      if (hasBeneficiary() != other.hasBeneficiary()) return false;
       if (hasBeneficiary()) {
-        result = result && getBeneficiary()
-            .equals(other.getBeneficiary());
+        if (!getBeneficiary()
+            .equals(other.getBeneficiary())) return false;
       }
-      result = result && (hasCostropasci() == other.hasCostropasci());
+      if (hasCostropasci() != other.hasCostropasci()) return false;
       if (hasCostropasci()) {
-        result = result && getCostropasci()
-            .equals(other.getCostropasci());
+        if (!getCostropasci()
+            .equals(other.getCostropasci())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -9630,50 +9614,50 @@ public ch.epfl.dedis.lib.proto.Personhood.SpawnerStruct buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.SpawnerStruct result = new ch.epfl.dedis.lib.proto.Personhood.SpawnerStruct(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (costdarcBuilder_ == null) {
+            result.costdarc_ = costdarc_;
+          } else {
+            result.costdarc_ = costdarcBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (costdarcBuilder_ == null) {
-          result.costdarc_ = costdarc_;
-        } else {
-          result.costdarc_ = costdarcBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (costcoinBuilder_ == null) {
+            result.costcoin_ = costcoin_;
+          } else {
+            result.costcoin_ = costcoinBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (costcoinBuilder_ == null) {
-          result.costcoin_ = costcoin_;
-        } else {
-          result.costcoin_ = costcoinBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          if (costcredentialBuilder_ == null) {
+            result.costcredential_ = costcredential_;
+          } else {
+            result.costcredential_ = costcredentialBuilder_.build();
+          }
           to_bitField0_ |= 0x00000004;
         }
-        if (costcredentialBuilder_ == null) {
-          result.costcredential_ = costcredential_;
-        } else {
-          result.costcredential_ = costcredentialBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          if (costpartyBuilder_ == null) {
+            result.costparty_ = costparty_;
+          } else {
+            result.costparty_ = costpartyBuilder_.build();
+          }
           to_bitField0_ |= 0x00000008;
         }
-        if (costpartyBuilder_ == null) {
-          result.costparty_ = costparty_;
-        } else {
-          result.costparty_ = costpartyBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((from_bitField0_ & 0x00000010) != 0)) {
           to_bitField0_ |= 0x00000010;
         }
         result.beneficiary_ = beneficiary_;
-        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+        if (((from_bitField0_ & 0x00000020) != 0)) {
+          if (costropasciBuilder_ == null) {
+            result.costropasci_ = costropasci_;
+          } else {
+            result.costropasci_ = costropasciBuilder_.build();
+          }
           to_bitField0_ |= 0x00000020;
         }
-        if (costropasciBuilder_ == null) {
-          result.costropasci_ = costropasci_;
-        } else {
-          result.costropasci_ = costropasciBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -9681,35 +9665,35 @@ public ch.epfl.dedis.lib.proto.Personhood.SpawnerStruct buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -9803,14 +9787,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin costdarc_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin costdarc_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Coin, ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder> costdarcBuilder_;
       /**
        * required .byzcoin.Coin costdarc = 1;
        */
       public boolean hasCostdarc() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required .byzcoin.Coin costdarc = 1;
@@ -9857,7 +9841,7 @@ public Builder setCostdarc(
        */
       public Builder mergeCostdarc(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin value) {
         if (costdarcBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               costdarc_ != null &&
               costdarc_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.getDefaultInstance()) {
             costdarc_ =
@@ -9921,14 +9905,14 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder getCostdarcOrBuilder()
         return costdarcBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin costcoin_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin costcoin_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Coin, ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder> costcoinBuilder_;
       /**
        * required .byzcoin.Coin costcoin = 2;
        */
       public boolean hasCostcoin() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required .byzcoin.Coin costcoin = 2;
@@ -9975,7 +9959,7 @@ public Builder setCostcoin(
        */
       public Builder mergeCostcoin(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin value) {
         if (costcoinBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               costcoin_ != null &&
               costcoin_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.getDefaultInstance()) {
             costcoin_ =
@@ -10039,14 +10023,14 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder getCostcoinOrBuilder()
         return costcoinBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin costcredential_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin costcredential_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Coin, ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder> costcredentialBuilder_;
       /**
        * required .byzcoin.Coin costcredential = 3;
        */
       public boolean hasCostcredential() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required .byzcoin.Coin costcredential = 3;
@@ -10093,7 +10077,7 @@ public Builder setCostcredential(
        */
       public Builder mergeCostcredential(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin value) {
         if (costcredentialBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+          if (((bitField0_ & 0x00000004) != 0) &&
               costcredential_ != null &&
               costcredential_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.getDefaultInstance()) {
             costcredential_ =
@@ -10157,14 +10141,14 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder getCostcredentialOrBui
         return costcredentialBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin costparty_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin costparty_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Coin, ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder> costpartyBuilder_;
       /**
        * required .byzcoin.Coin costparty = 4;
        */
       public boolean hasCostparty() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * required .byzcoin.Coin costparty = 4;
@@ -10211,7 +10195,7 @@ public Builder setCostparty(
        */
       public Builder mergeCostparty(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin value) {
         if (costpartyBuilder_ == null) {
-          if (((bitField0_ & 0x00000008) == 0x00000008) &&
+          if (((bitField0_ & 0x00000008) != 0) &&
               costparty_ != null &&
               costparty_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.getDefaultInstance()) {
             costparty_ =
@@ -10280,7 +10264,7 @@ public ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder getCostpartyOrBuilder(
        * required bytes beneficiary = 5;
        */
       public boolean hasBeneficiary() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return ((bitField0_ & 0x00000010) != 0);
       }
       /**
        * required bytes beneficiary = 5;
@@ -10310,14 +10294,14 @@ public Builder clearBeneficiary() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin costropasci_ = null;
+      private ch.epfl.dedis.lib.proto.ByzCoinProto.Coin costropasci_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.ByzCoinProto.Coin, ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.CoinOrBuilder> costropasciBuilder_;
       /**
        * optional .byzcoin.Coin costropasci = 6;
        */
       public boolean hasCostropasci() {
-        return ((bitField0_ & 0x00000020) == 0x00000020);
+        return ((bitField0_ & 0x00000020) != 0);
       }
       /**
        * optional .byzcoin.Coin costropasci = 6;
@@ -10364,7 +10348,7 @@ public Builder setCostropasci(
        */
       public Builder mergeCostropasci(ch.epfl.dedis.lib.proto.ByzCoinProto.Coin value) {
         if (costropasciBuilder_ == null) {
-          if (((bitField0_ & 0x00000020) == 0x00000020) &&
+          if (((bitField0_ & 0x00000020) != 0) &&
               costropasci_ != null &&
               costropasci_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Coin.getDefaultInstance()) {
             costropasci_ =
@@ -10737,11 +10721,8 @@ private PopPartyStruct(com.google.protobuf.GeneratedMessageV3.Builder builder
       super(builder);
     }
     private PopPartyStruct() {
-      state_ = 0;
-      organizers_ = 0;
       finalizations_ = com.google.protobuf.LazyStringArrayList.EMPTY;
       miners_ = java.util.Collections.emptyList();
-      miningreward_ = 0L;
       previous_ = com.google.protobuf.ByteString.EMPTY;
       next_ = com.google.protobuf.ByteString.EMPTY;
     }
@@ -10782,7 +10763,7 @@ private PopPartyStruct(
             }
             case 26: {
               com.google.protobuf.ByteString bs = input.readBytes();
-              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+              if (!((mutable_bitField0_ & 0x00000004) != 0)) {
                 finalizations_ = new com.google.protobuf.LazyStringArrayList();
                 mutable_bitField0_ |= 0x00000004;
               }
@@ -10791,7 +10772,7 @@ private PopPartyStruct(
             }
             case 34: {
               ch.epfl.dedis.lib.proto.Personhood.PopDesc.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (((bitField0_ & 0x00000004) != 0)) {
                 subBuilder = description_.toBuilder();
               }
               description_ = input.readMessage(ch.epfl.dedis.lib.proto.Personhood.PopDesc.parser(), extensionRegistry);
@@ -10804,7 +10785,7 @@ private PopPartyStruct(
             }
             case 42: {
               ch.epfl.dedis.lib.proto.Personhood.Attendees.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000008) == 0x00000008)) {
+              if (((bitField0_ & 0x00000008) != 0)) {
                 subBuilder = attendees_.toBuilder();
               }
               attendees_ = input.readMessage(ch.epfl.dedis.lib.proto.Personhood.Attendees.parser(), extensionRegistry);
@@ -10816,7 +10797,7 @@ private PopPartyStruct(
               break;
             }
             case 50: {
-              if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+              if (!((mutable_bitField0_ & 0x00000020) != 0)) {
                 miners_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000020;
               }
@@ -10854,10 +10835,10 @@ private PopPartyStruct(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((mutable_bitField0_ & 0x00000004) != 0)) {
           finalizations_ = finalizations_.getUnmodifiableView();
         }
-        if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+        if (((mutable_bitField0_ & 0x00000020) != 0)) {
           miners_ = java.util.Collections.unmodifiableList(miners_);
         }
         this.unknownFields = unknownFields.build();
@@ -10891,7 +10872,7 @@ private PopPartyStruct(
      * required sint32 state = 1;
      */
     public boolean hasState() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -10917,7 +10898,7 @@ public int getState() {
      * required sint32 organizers = 2;
      */
     public boolean hasOrganizers() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -10990,7 +10971,7 @@ public java.lang.String getFinalizations(int index) {
      * required .personhood.PopDesc description = 4;
      */
     public boolean hasDescription() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -11025,7 +11006,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PopDescOrBuilder getDescriptionOrBuild
      * required .personhood.Attendees attendees = 5;
      */
     public boolean hasAttendees() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * 
@@ -11118,7 +11099,7 @@ public ch.epfl.dedis.lib.proto.Personhood.LRSTagOrBuilder getMinersOrBuilder(
      * required uint64 miningreward = 7;
      */
     public boolean hasMiningreward() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * 
@@ -11142,7 +11123,7 @@ public long getMiningreward() {
      * optional bytes previous = 8;
      */
     public boolean hasPrevious() {
-      return ((bitField0_ & 0x00000020) == 0x00000020);
+      return ((bitField0_ & 0x00000020) != 0);
     }
     /**
      * 
@@ -11167,7 +11148,7 @@ public com.google.protobuf.ByteString getPrevious() {
      * optional bytes next = 9;
      */
     public boolean hasNext() {
-      return ((bitField0_ & 0x00000040) == 0x00000040);
+      return ((bitField0_ & 0x00000040) != 0);
     }
     /**
      * 
@@ -11225,31 +11206,31 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, state_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeSInt32(2, organizers_);
       }
       for (int i = 0; i < finalizations_.size(); i++) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 3, finalizations_.getRaw(i));
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeMessage(4, getDescription());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeMessage(5, getAttendees());
       }
       for (int i = 0; i < miners_.size(); i++) {
         output.writeMessage(6, miners_.get(i));
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         output.writeUInt64(7, miningreward_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         output.writeBytes(8, previous_);
       }
-      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+      if (((bitField0_ & 0x00000040) != 0)) {
         output.writeBytes(9, next_);
       }
       unknownFields.writeTo(output);
@@ -11261,11 +11242,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, state_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(2, organizers_);
       }
@@ -11277,11 +11258,11 @@ public int getSerializedSize() {
         size += dataSize;
         size += 1 * getFinalizationsList().size();
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(4, getDescription());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(5, getAttendees());
       }
@@ -11289,15 +11270,15 @@ public int getSerializedSize() {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(6, miners_.get(i));
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(7, miningreward_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(8, previous_);
       }
-      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+      if (((bitField0_ & 0x00000040) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(9, next_);
       }
@@ -11316,48 +11297,47 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.PopPartyStruct other = (ch.epfl.dedis.lib.proto.Personhood.PopPartyStruct) obj;
 
-      boolean result = true;
-      result = result && (hasState() == other.hasState());
+      if (hasState() != other.hasState()) return false;
       if (hasState()) {
-        result = result && (getState()
-            == other.getState());
+        if (getState()
+            != other.getState()) return false;
       }
-      result = result && (hasOrganizers() == other.hasOrganizers());
+      if (hasOrganizers() != other.hasOrganizers()) return false;
       if (hasOrganizers()) {
-        result = result && (getOrganizers()
-            == other.getOrganizers());
+        if (getOrganizers()
+            != other.getOrganizers()) return false;
       }
-      result = result && getFinalizationsList()
-          .equals(other.getFinalizationsList());
-      result = result && (hasDescription() == other.hasDescription());
+      if (!getFinalizationsList()
+          .equals(other.getFinalizationsList())) return false;
+      if (hasDescription() != other.hasDescription()) return false;
       if (hasDescription()) {
-        result = result && getDescription()
-            .equals(other.getDescription());
+        if (!getDescription()
+            .equals(other.getDescription())) return false;
       }
-      result = result && (hasAttendees() == other.hasAttendees());
+      if (hasAttendees() != other.hasAttendees()) return false;
       if (hasAttendees()) {
-        result = result && getAttendees()
-            .equals(other.getAttendees());
+        if (!getAttendees()
+            .equals(other.getAttendees())) return false;
       }
-      result = result && getMinersList()
-          .equals(other.getMinersList());
-      result = result && (hasMiningreward() == other.hasMiningreward());
+      if (!getMinersList()
+          .equals(other.getMinersList())) return false;
+      if (hasMiningreward() != other.hasMiningreward()) return false;
       if (hasMiningreward()) {
-        result = result && (getMiningreward()
-            == other.getMiningreward());
+        if (getMiningreward()
+            != other.getMiningreward()) return false;
       }
-      result = result && (hasPrevious() == other.hasPrevious());
+      if (hasPrevious() != other.hasPrevious()) return false;
       if (hasPrevious()) {
-        result = result && getPrevious()
-            .equals(other.getPrevious());
+        if (!getPrevious()
+            .equals(other.getPrevious())) return false;
       }
-      result = result && (hasNext() == other.hasNext());
+      if (hasNext() != other.hasNext()) return false;
       if (hasNext()) {
-        result = result && getNext()
-            .equals(other.getNext());
+        if (!getNext()
+            .equals(other.getNext())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -11602,37 +11582,37 @@ public ch.epfl.dedis.lib.proto.Personhood.PopPartyStruct buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.PopPartyStruct result = new ch.epfl.dedis.lib.proto.Personhood.PopPartyStruct(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.state_ = state_;
           to_bitField0_ |= 0x00000001;
         }
-        result.state_ = state_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.organizers_ = organizers_;
           to_bitField0_ |= 0x00000002;
         }
-        result.organizers_ = organizers_;
-        if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((bitField0_ & 0x00000004) != 0)) {
           finalizations_ = finalizations_.getUnmodifiableView();
           bitField0_ = (bitField0_ & ~0x00000004);
         }
         result.finalizations_ = finalizations_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          if (descriptionBuilder_ == null) {
+            result.description_ = description_;
+          } else {
+            result.description_ = descriptionBuilder_.build();
+          }
           to_bitField0_ |= 0x00000004;
         }
-        if (descriptionBuilder_ == null) {
-          result.description_ = description_;
-        } else {
-          result.description_ = descriptionBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((from_bitField0_ & 0x00000010) != 0)) {
+          if (attendeesBuilder_ == null) {
+            result.attendees_ = attendees_;
+          } else {
+            result.attendees_ = attendeesBuilder_.build();
+          }
           to_bitField0_ |= 0x00000008;
         }
-        if (attendeesBuilder_ == null) {
-          result.attendees_ = attendees_;
-        } else {
-          result.attendees_ = attendeesBuilder_.build();
-        }
         if (minersBuilder_ == null) {
-          if (((bitField0_ & 0x00000020) == 0x00000020)) {
+          if (((bitField0_ & 0x00000020) != 0)) {
             miners_ = java.util.Collections.unmodifiableList(miners_);
             bitField0_ = (bitField0_ & ~0x00000020);
           }
@@ -11640,15 +11620,15 @@ public ch.epfl.dedis.lib.proto.Personhood.PopPartyStruct buildPartial() {
         } else {
           result.miners_ = minersBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
+        if (((from_bitField0_ & 0x00000040) != 0)) {
+          result.miningreward_ = miningreward_;
           to_bitField0_ |= 0x00000010;
         }
-        result.miningreward_ = miningreward_;
-        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
+        if (((from_bitField0_ & 0x00000080) != 0)) {
           to_bitField0_ |= 0x00000020;
         }
         result.previous_ = previous_;
-        if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
+        if (((from_bitField0_ & 0x00000100) != 0)) {
           to_bitField0_ |= 0x00000040;
         }
         result.next_ = next_;
@@ -11659,35 +11639,35 @@ public ch.epfl.dedis.lib.proto.Personhood.PopPartyStruct buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -11823,7 +11803,7 @@ public Builder mergeFrom(
        * required sint32 state = 1;
        */
       public boolean hasState() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -11880,7 +11860,7 @@ public Builder clearState() {
        * required sint32 organizers = 2;
        */
       public boolean hasOrganizers() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -11921,7 +11901,7 @@ public Builder clearOrganizers() {
 
       private com.google.protobuf.LazyStringList finalizations_ = com.google.protobuf.LazyStringArrayList.EMPTY;
       private void ensureFinalizationsIsMutable() {
-        if (!((bitField0_ & 0x00000004) == 0x00000004)) {
+        if (!((bitField0_ & 0x00000004) != 0)) {
           finalizations_ = new com.google.protobuf.LazyStringArrayList(finalizations_);
           bitField0_ |= 0x00000004;
          }
@@ -12057,7 +12037,7 @@ public Builder addFinalizationsBytes(
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.Personhood.PopDesc description_ = null;
+      private ch.epfl.dedis.lib.proto.Personhood.PopDesc description_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.Personhood.PopDesc, ch.epfl.dedis.lib.proto.Personhood.PopDesc.Builder, ch.epfl.dedis.lib.proto.Personhood.PopDescOrBuilder> descriptionBuilder_;
       /**
@@ -12069,7 +12049,7 @@ public Builder addFinalizationsBytes(
        * required .personhood.PopDesc description = 4;
        */
       public boolean hasDescription() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * 
@@ -12136,7 +12116,7 @@ public Builder setDescription(
        */
       public Builder mergeDescription(ch.epfl.dedis.lib.proto.Personhood.PopDesc value) {
         if (descriptionBuilder_ == null) {
-          if (((bitField0_ & 0x00000008) == 0x00000008) &&
+          if (((bitField0_ & 0x00000008) != 0) &&
               description_ != null &&
               description_ != ch.epfl.dedis.lib.proto.Personhood.PopDesc.getDefaultInstance()) {
             description_ =
@@ -12220,7 +12200,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PopDescOrBuilder getDescriptionOrBuild
         return descriptionBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.Personhood.Attendees attendees_ = null;
+      private ch.epfl.dedis.lib.proto.Personhood.Attendees attendees_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.Personhood.Attendees, ch.epfl.dedis.lib.proto.Personhood.Attendees.Builder, ch.epfl.dedis.lib.proto.Personhood.AttendeesOrBuilder> attendeesBuilder_;
       /**
@@ -12231,7 +12211,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PopDescOrBuilder getDescriptionOrBuild
        * required .personhood.Attendees attendees = 5;
        */
       public boolean hasAttendees() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return ((bitField0_ & 0x00000010) != 0);
       }
       /**
        * 
@@ -12294,7 +12274,7 @@ public Builder setAttendees(
        */
       public Builder mergeAttendees(ch.epfl.dedis.lib.proto.Personhood.Attendees value) {
         if (attendeesBuilder_ == null) {
-          if (((bitField0_ & 0x00000010) == 0x00000010) &&
+          if (((bitField0_ & 0x00000010) != 0) &&
               attendees_ != null &&
               attendees_ != ch.epfl.dedis.lib.proto.Personhood.Attendees.getDefaultInstance()) {
             attendees_ =
@@ -12377,7 +12357,7 @@ public ch.epfl.dedis.lib.proto.Personhood.AttendeesOrBuilder getAttendeesOrBuild
       private java.util.List miners_ =
         java.util.Collections.emptyList();
       private void ensureMinersIsMutable() {
-        if (!((bitField0_ & 0x00000020) == 0x00000020)) {
+        if (!((bitField0_ & 0x00000020) != 0)) {
           miners_ = new java.util.ArrayList(miners_);
           bitField0_ |= 0x00000020;
          }
@@ -12696,7 +12676,7 @@ public ch.epfl.dedis.lib.proto.Personhood.LRSTag.Builder addMinersBuilder(
           minersBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.Personhood.LRSTag, ch.epfl.dedis.lib.proto.Personhood.LRSTag.Builder, ch.epfl.dedis.lib.proto.Personhood.LRSTagOrBuilder>(
                   miners_,
-                  ((bitField0_ & 0x00000020) == 0x00000020),
+                  ((bitField0_ & 0x00000020) != 0),
                   getParentForChildren(),
                   isClean());
           miners_ = null;
@@ -12713,7 +12693,7 @@ public ch.epfl.dedis.lib.proto.Personhood.LRSTag.Builder addMinersBuilder(
        * required uint64 miningreward = 7;
        */
       public boolean hasMiningreward() {
-        return ((bitField0_ & 0x00000040) == 0x00000040);
+        return ((bitField0_ & 0x00000040) != 0);
       }
       /**
        * 
@@ -12762,7 +12742,7 @@ public Builder clearMiningreward() {
        * optional bytes previous = 8;
        */
       public boolean hasPrevious() {
-        return ((bitField0_ & 0x00000080) == 0x00000080);
+        return ((bitField0_ & 0x00000080) != 0);
       }
       /**
        * 
@@ -12817,7 +12797,7 @@ public Builder clearPrevious() {
        * optional bytes next = 9;
        */
       public boolean hasNext() {
-        return ((bitField0_ & 0x00000100) == 0x00000100);
+        return ((bitField0_ & 0x00000100) != 0);
       }
       /**
        * 
@@ -13032,7 +13012,6 @@ private PopDesc(com.google.protobuf.GeneratedMessageV3.Builder builder) {
     private PopDesc() {
       name_ = "";
       purpose_ = "";
-      datetime_ = 0L;
       location_ = "";
     }
 
@@ -13126,7 +13105,7 @@ private PopDesc(
      * required string name = 1;
      */
     public boolean hasName() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -13180,7 +13159,7 @@ public java.lang.String getName() {
      * required string purpose = 2;
      */
     public boolean hasPurpose() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -13234,7 +13213,7 @@ public java.lang.String getPurpose() {
      * required uint64 datetime = 3;
      */
     public boolean hasDatetime() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * 
@@ -13257,7 +13236,7 @@ public long getDatetime() {
      * required string location = 4;
      */
     public boolean hasLocation() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * 
@@ -13331,16 +13310,16 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 2, purpose_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeUInt64(3, datetime_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 4, location_);
       }
       unknownFields.writeTo(output);
@@ -13352,17 +13331,17 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, purpose_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(3, datetime_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, location_);
       }
       size += unknownFields.getSerializedSize();
@@ -13380,29 +13359,28 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.PopDesc other = (ch.epfl.dedis.lib.proto.Personhood.PopDesc) obj;
 
-      boolean result = true;
-      result = result && (hasName() == other.hasName());
+      if (hasName() != other.hasName()) return false;
       if (hasName()) {
-        result = result && getName()
-            .equals(other.getName());
+        if (!getName()
+            .equals(other.getName())) return false;
       }
-      result = result && (hasPurpose() == other.hasPurpose());
+      if (hasPurpose() != other.hasPurpose()) return false;
       if (hasPurpose()) {
-        result = result && getPurpose()
-            .equals(other.getPurpose());
+        if (!getPurpose()
+            .equals(other.getPurpose())) return false;
       }
-      result = result && (hasDatetime() == other.hasDatetime());
+      if (hasDatetime() != other.hasDatetime()) return false;
       if (hasDatetime()) {
-        result = result && (getDatetime()
-            == other.getDatetime());
+        if (getDatetime()
+            != other.getDatetime()) return false;
       }
-      result = result && (hasLocation() == other.hasLocation());
+      if (hasLocation() != other.hasLocation()) return false;
       if (hasLocation()) {
-        result = result && getLocation()
-            .equals(other.getLocation());
+        if (!getLocation()
+            .equals(other.getLocation())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -13602,19 +13580,19 @@ public ch.epfl.dedis.lib.proto.Personhood.PopDesc buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.PopDesc result = new ch.epfl.dedis.lib.proto.Personhood.PopDesc(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.name_ = name_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.purpose_ = purpose_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          result.datetime_ = datetime_;
           to_bitField0_ |= 0x00000004;
         }
-        result.datetime_ = datetime_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
           to_bitField0_ |= 0x00000008;
         }
         result.location_ = location_;
@@ -13625,35 +13603,35 @@ public ch.epfl.dedis.lib.proto.Personhood.PopDesc buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -13736,7 +13714,7 @@ public Builder mergeFrom(
        * required string name = 1;
        */
       public boolean hasName() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -13836,7 +13814,7 @@ public Builder setNameBytes(
        * required string purpose = 2;
        */
       public boolean hasPurpose() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -13936,7 +13914,7 @@ public Builder setPurposeBytes(
        * required uint64 datetime = 3;
        */
       public boolean hasDatetime() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * 
@@ -13984,7 +13962,7 @@ public Builder clearDatetime() {
        * required string location = 4;
        */
       public boolean hasLocation() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * 
@@ -14227,7 +14205,7 @@ private FinalStatement(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.Personhood.PopDesc.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = desc_.toBuilder();
               }
               desc_ = input.readMessage(ch.epfl.dedis.lib.proto.Personhood.PopDesc.parser(), extensionRegistry);
@@ -14240,7 +14218,7 @@ private FinalStatement(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.Personhood.Attendees.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = attendees_.toBuilder();
               }
               attendees_ = input.readMessage(ch.epfl.dedis.lib.proto.Personhood.Attendees.parser(), extensionRegistry);
@@ -14294,7 +14272,7 @@ private FinalStatement(
      * optional .personhood.PopDesc desc = 1;
      */
     public boolean hasDesc() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -14327,7 +14305,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PopDescOrBuilder getDescOrBuilder() {
      * required .personhood.Attendees attendees = 2;
      */
     public boolean hasAttendees() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * 
@@ -14374,10 +14352,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getDesc());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getAttendees());
       }
       unknownFields.writeTo(output);
@@ -14389,11 +14367,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getDesc());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getAttendees());
       }
@@ -14412,19 +14390,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.FinalStatement other = (ch.epfl.dedis.lib.proto.Personhood.FinalStatement) obj;
 
-      boolean result = true;
-      result = result && (hasDesc() == other.hasDesc());
+      if (hasDesc() != other.hasDesc()) return false;
       if (hasDesc()) {
-        result = result && getDesc()
-            .equals(other.getDesc());
+        if (!getDesc()
+            .equals(other.getDesc())) return false;
       }
-      result = result && (hasAttendees() == other.hasAttendees());
+      if (hasAttendees() != other.hasAttendees()) return false;
       if (hasAttendees()) {
-        result = result && getAttendees()
-            .equals(other.getAttendees());
+        if (!getAttendees()
+            .equals(other.getAttendees())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -14622,22 +14599,22 @@ public ch.epfl.dedis.lib.proto.Personhood.FinalStatement buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.FinalStatement result = new ch.epfl.dedis.lib.proto.Personhood.FinalStatement(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (descBuilder_ == null) {
+            result.desc_ = desc_;
+          } else {
+            result.desc_ = descBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (descBuilder_ == null) {
-          result.desc_ = desc_;
-        } else {
-          result.desc_ = descBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (attendeesBuilder_ == null) {
+            result.attendees_ = attendees_;
+          } else {
+            result.attendees_ = attendeesBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (attendeesBuilder_ == null) {
-          result.attendees_ = attendees_;
-        } else {
-          result.attendees_ = attendeesBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -14645,35 +14622,35 @@ public ch.epfl.dedis.lib.proto.Personhood.FinalStatement buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -14731,7 +14708,7 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.Personhood.PopDesc desc_ = null;
+      private ch.epfl.dedis.lib.proto.Personhood.PopDesc desc_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.Personhood.PopDesc, ch.epfl.dedis.lib.proto.Personhood.PopDesc.Builder, ch.epfl.dedis.lib.proto.Personhood.PopDescOrBuilder> descBuilder_;
       /**
@@ -14742,7 +14719,7 @@ public Builder mergeFrom(
        * optional .personhood.PopDesc desc = 1;
        */
       public boolean hasDesc() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -14805,7 +14782,7 @@ public Builder setDesc(
        */
       public Builder mergeDesc(ch.epfl.dedis.lib.proto.Personhood.PopDesc value) {
         if (descBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               desc_ != null &&
               desc_ != ch.epfl.dedis.lib.proto.Personhood.PopDesc.getDefaultInstance()) {
             desc_ =
@@ -14885,7 +14862,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PopDescOrBuilder getDescOrBuilder() {
         return descBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.Personhood.Attendees attendees_ = null;
+      private ch.epfl.dedis.lib.proto.Personhood.Attendees attendees_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.Personhood.Attendees, ch.epfl.dedis.lib.proto.Personhood.Attendees.Builder, ch.epfl.dedis.lib.proto.Personhood.AttendeesOrBuilder> attendeesBuilder_;
       /**
@@ -14896,7 +14873,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PopDescOrBuilder getDescOrBuilder() {
        * required .personhood.Attendees attendees = 2;
        */
       public boolean hasAttendees() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * 
@@ -14959,7 +14936,7 @@ public Builder setAttendees(
        */
       public Builder mergeAttendees(ch.epfl.dedis.lib.proto.Personhood.Attendees value) {
         if (attendeesBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               attendees_ != null &&
               attendees_ != ch.epfl.dedis.lib.proto.Personhood.Attendees.getDefaultInstance()) {
             attendees_ =
@@ -15153,7 +15130,7 @@ private Attendees(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 keys_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -15175,8 +15152,8 @@ private Attendees(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-          keys_ = java.util.Collections.unmodifiableList(keys_);
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          keys_ = java.util.Collections.unmodifiableList(keys_); // C
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -15267,11 +15244,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.Attendees other = (ch.epfl.dedis.lib.proto.Personhood.Attendees) obj;
 
-      boolean result = true;
-      result = result && getKeysList()
-          .equals(other.getKeysList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getKeysList()
+          .equals(other.getKeysList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -15451,7 +15427,7 @@ public ch.epfl.dedis.lib.proto.Personhood.Attendees build() {
       public ch.epfl.dedis.lib.proto.Personhood.Attendees buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.Attendees result = new ch.epfl.dedis.lib.proto.Personhood.Attendees(this);
         int from_bitField0_ = bitField0_;
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((bitField0_ & 0x00000001) != 0)) {
           keys_ = java.util.Collections.unmodifiableList(keys_);
           bitField0_ = (bitField0_ & ~0x00000001);
         }
@@ -15462,35 +15438,35 @@ public ch.epfl.dedis.lib.proto.Personhood.Attendees buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -15546,7 +15522,7 @@ public Builder mergeFrom(
 
       private java.util.List keys_ = java.util.Collections.emptyList();
       private void ensureKeysIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           keys_ = new java.util.ArrayList(keys_);
           bitField0_ |= 0x00000001;
          }
@@ -15556,7 +15532,8 @@ private void ensureKeysIsMutable() {
        */
       public java.util.List
           getKeysList() {
-        return java.util.Collections.unmodifiableList(keys_);
+        return ((bitField0_ & 0x00000001) != 0) ?
+                 java.util.Collections.unmodifiableList(keys_) : keys_;
       }
       /**
        * repeated bytes keys = 1;
@@ -15769,7 +15746,7 @@ private LRSTag(
      * required bytes tag = 1;
      */
     public boolean hasTag() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes tag = 1;
@@ -15796,7 +15773,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, tag_);
       }
       unknownFields.writeTo(output);
@@ -15808,7 +15785,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, tag_);
       }
@@ -15827,14 +15804,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.LRSTag other = (ch.epfl.dedis.lib.proto.Personhood.LRSTag) obj;
 
-      boolean result = true;
-      result = result && (hasTag() == other.hasTag());
+      if (hasTag() != other.hasTag()) return false;
       if (hasTag()) {
-        result = result && getTag()
-            .equals(other.getTag());
+        if (!getTag()
+            .equals(other.getTag())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -16015,7 +15991,7 @@ public ch.epfl.dedis.lib.proto.Personhood.LRSTag buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.LRSTag result = new ch.epfl.dedis.lib.proto.Personhood.LRSTag(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.tag_ = tag_;
@@ -16026,35 +16002,35 @@ public ch.epfl.dedis.lib.proto.Personhood.LRSTag buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -16109,7 +16085,7 @@ public Builder mergeFrom(
        * required bytes tag = 1;
        */
       public boolean hasTag() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes tag = 1;
@@ -16294,7 +16270,7 @@ private Poll(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.Personhood.PollStruct.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = newpoll_.toBuilder();
               }
               newpoll_ = input.readMessage(ch.epfl.dedis.lib.proto.Personhood.PollStruct.parser(), extensionRegistry);
@@ -16307,7 +16283,7 @@ private Poll(
             }
             case 26: {
               ch.epfl.dedis.lib.proto.Personhood.PollList.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (((bitField0_ & 0x00000004) != 0)) {
                 subBuilder = list_.toBuilder();
               }
               list_ = input.readMessage(ch.epfl.dedis.lib.proto.Personhood.PollList.parser(), extensionRegistry);
@@ -16320,7 +16296,7 @@ private Poll(
             }
             case 34: {
               ch.epfl.dedis.lib.proto.Personhood.PollAnswer.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000008) == 0x00000008)) {
+              if (((bitField0_ & 0x00000008) != 0)) {
                 subBuilder = answer_.toBuilder();
               }
               answer_ = input.readMessage(ch.epfl.dedis.lib.proto.Personhood.PollAnswer.parser(), extensionRegistry);
@@ -16370,7 +16346,7 @@ private Poll(
      * required bytes byzcoinid = 1;
      */
     public boolean hasByzcoinid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes byzcoinid = 1;
@@ -16385,7 +16361,7 @@ public com.google.protobuf.ByteString getByzcoinid() {
      * optional .personhood.PollStruct newpoll = 2;
      */
     public boolean hasNewpoll() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * optional .personhood.PollStruct newpoll = 2;
@@ -16406,7 +16382,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PollStructOrBuilder getNewpollOrBuilde
      * optional .personhood.PollList list = 3;
      */
     public boolean hasList() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * optional .personhood.PollList list = 3;
@@ -16427,7 +16403,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PollListOrBuilder getListOrBuilder() {
      * optional .personhood.PollAnswer answer = 4;
      */
     public boolean hasAnswer() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * optional .personhood.PollAnswer answer = 4;
@@ -16472,16 +16448,16 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getNewpoll());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeMessage(3, getList());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeMessage(4, getAnswer());
       }
       unknownFields.writeTo(output);
@@ -16493,19 +16469,19 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, byzcoinid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getNewpoll());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getList());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(4, getAnswer());
       }
@@ -16524,29 +16500,28 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.Poll other = (ch.epfl.dedis.lib.proto.Personhood.Poll) obj;
 
-      boolean result = true;
-      result = result && (hasByzcoinid() == other.hasByzcoinid());
+      if (hasByzcoinid() != other.hasByzcoinid()) return false;
       if (hasByzcoinid()) {
-        result = result && getByzcoinid()
-            .equals(other.getByzcoinid());
+        if (!getByzcoinid()
+            .equals(other.getByzcoinid())) return false;
       }
-      result = result && (hasNewpoll() == other.hasNewpoll());
+      if (hasNewpoll() != other.hasNewpoll()) return false;
       if (hasNewpoll()) {
-        result = result && getNewpoll()
-            .equals(other.getNewpoll());
+        if (!getNewpoll()
+            .equals(other.getNewpoll())) return false;
       }
-      result = result && (hasList() == other.hasList());
+      if (hasList() != other.hasList()) return false;
       if (hasList()) {
-        result = result && getList()
-            .equals(other.getList());
+        if (!getList()
+            .equals(other.getList())) return false;
       }
-      result = result && (hasAnswer() == other.hasAnswer());
+      if (hasAnswer() != other.hasAnswer()) return false;
       if (hasAnswer()) {
-        result = result && getAnswer()
-            .equals(other.getAnswer());
+        if (!getAnswer()
+            .equals(other.getAnswer())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -16760,34 +16735,34 @@ public ch.epfl.dedis.lib.proto.Personhood.Poll buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.Poll result = new ch.epfl.dedis.lib.proto.Personhood.Poll(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.byzcoinid_ = byzcoinid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (newpollBuilder_ == null) {
+            result.newpoll_ = newpoll_;
+          } else {
+            result.newpoll_ = newpollBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (newpollBuilder_ == null) {
-          result.newpoll_ = newpoll_;
-        } else {
-          result.newpoll_ = newpollBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          if (listBuilder_ == null) {
+            result.list_ = list_;
+          } else {
+            result.list_ = listBuilder_.build();
+          }
           to_bitField0_ |= 0x00000004;
         }
-        if (listBuilder_ == null) {
-          result.list_ = list_;
-        } else {
-          result.list_ = listBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          if (answerBuilder_ == null) {
+            result.answer_ = answer_;
+          } else {
+            result.answer_ = answerBuilder_.build();
+          }
           to_bitField0_ |= 0x00000008;
         }
-        if (answerBuilder_ == null) {
-          result.answer_ = answer_;
-        } else {
-          result.answer_ = answerBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -16795,35 +16770,35 @@ public ch.epfl.dedis.lib.proto.Personhood.Poll buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -16897,7 +16872,7 @@ public Builder mergeFrom(
        * required bytes byzcoinid = 1;
        */
       public boolean hasByzcoinid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes byzcoinid = 1;
@@ -16927,14 +16902,14 @@ public Builder clearByzcoinid() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.Personhood.PollStruct newpoll_ = null;
+      private ch.epfl.dedis.lib.proto.Personhood.PollStruct newpoll_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.Personhood.PollStruct, ch.epfl.dedis.lib.proto.Personhood.PollStruct.Builder, ch.epfl.dedis.lib.proto.Personhood.PollStructOrBuilder> newpollBuilder_;
       /**
        * optional .personhood.PollStruct newpoll = 2;
        */
       public boolean hasNewpoll() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * optional .personhood.PollStruct newpoll = 2;
@@ -16981,7 +16956,7 @@ public Builder setNewpoll(
        */
       public Builder mergeNewpoll(ch.epfl.dedis.lib.proto.Personhood.PollStruct value) {
         if (newpollBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               newpoll_ != null &&
               newpoll_ != ch.epfl.dedis.lib.proto.Personhood.PollStruct.getDefaultInstance()) {
             newpoll_ =
@@ -17045,14 +17020,14 @@ public ch.epfl.dedis.lib.proto.Personhood.PollStructOrBuilder getNewpollOrBuilde
         return newpollBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.Personhood.PollList list_ = null;
+      private ch.epfl.dedis.lib.proto.Personhood.PollList list_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.Personhood.PollList, ch.epfl.dedis.lib.proto.Personhood.PollList.Builder, ch.epfl.dedis.lib.proto.Personhood.PollListOrBuilder> listBuilder_;
       /**
        * optional .personhood.PollList list = 3;
        */
       public boolean hasList() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * optional .personhood.PollList list = 3;
@@ -17099,7 +17074,7 @@ public Builder setList(
        */
       public Builder mergeList(ch.epfl.dedis.lib.proto.Personhood.PollList value) {
         if (listBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+          if (((bitField0_ & 0x00000004) != 0) &&
               list_ != null &&
               list_ != ch.epfl.dedis.lib.proto.Personhood.PollList.getDefaultInstance()) {
             list_ =
@@ -17163,14 +17138,14 @@ public ch.epfl.dedis.lib.proto.Personhood.PollListOrBuilder getListOrBuilder() {
         return listBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.Personhood.PollAnswer answer_ = null;
+      private ch.epfl.dedis.lib.proto.Personhood.PollAnswer answer_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.Personhood.PollAnswer, ch.epfl.dedis.lib.proto.Personhood.PollAnswer.Builder, ch.epfl.dedis.lib.proto.Personhood.PollAnswerOrBuilder> answerBuilder_;
       /**
        * optional .personhood.PollAnswer answer = 4;
        */
       public boolean hasAnswer() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * optional .personhood.PollAnswer answer = 4;
@@ -17217,7 +17192,7 @@ public Builder setAnswer(
        */
       public Builder mergeAnswer(ch.epfl.dedis.lib.proto.Personhood.PollAnswer value) {
         if (answerBuilder_ == null) {
-          if (((bitField0_ & 0x00000008) == 0x00000008) &&
+          if (((bitField0_ & 0x00000008) != 0) &&
               answer_ != null &&
               answer_ != ch.epfl.dedis.lib.proto.Personhood.PollAnswer.getDefaultInstance()) {
             answer_ =
@@ -17395,7 +17370,7 @@ private PollList(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 partyids_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -17417,8 +17392,8 @@ private PollList(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-          partyids_ = java.util.Collections.unmodifiableList(partyids_);
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          partyids_ = java.util.Collections.unmodifiableList(partyids_); // C
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -17509,11 +17484,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.PollList other = (ch.epfl.dedis.lib.proto.Personhood.PollList) obj;
 
-      boolean result = true;
-      result = result && getPartyidsList()
-          .equals(other.getPartyidsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getPartyidsList()
+          .equals(other.getPartyidsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -17693,7 +17667,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PollList build() {
       public ch.epfl.dedis.lib.proto.Personhood.PollList buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.PollList result = new ch.epfl.dedis.lib.proto.Personhood.PollList(this);
         int from_bitField0_ = bitField0_;
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((bitField0_ & 0x00000001) != 0)) {
           partyids_ = java.util.Collections.unmodifiableList(partyids_);
           bitField0_ = (bitField0_ & ~0x00000001);
         }
@@ -17704,35 +17678,35 @@ public ch.epfl.dedis.lib.proto.Personhood.PollList buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -17788,7 +17762,7 @@ public Builder mergeFrom(
 
       private java.util.List partyids_ = java.util.Collections.emptyList();
       private void ensurePartyidsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           partyids_ = new java.util.ArrayList(partyids_);
           bitField0_ |= 0x00000001;
          }
@@ -17798,7 +17772,8 @@ private void ensurePartyidsIsMutable() {
        */
       public java.util.List
           getPartyidsList() {
-        return java.util.Collections.unmodifiableList(partyids_);
+        return ((bitField0_ & 0x00000001) != 0) ?
+                 java.util.Collections.unmodifiableList(partyids_) : partyids_;
       }
       /**
        * repeated bytes partyids = 1;
@@ -17963,7 +17938,6 @@ private PollAnswer(com.google.protobuf.GeneratedMessageV3.Builder builder) {
     }
     private PollAnswer() {
       pollid_ = com.google.protobuf.ByteString.EMPTY;
-      choice_ = 0;
       lrs_ = com.google.protobuf.ByteString.EMPTY;
     }
 
@@ -18045,7 +18019,7 @@ private PollAnswer(
      * required bytes pollid = 1;
      */
     public boolean hasPollid() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes pollid = 1;
@@ -18060,7 +18034,7 @@ public com.google.protobuf.ByteString getPollid() {
      * required sint32 choice = 2;
      */
     public boolean hasChoice() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required sint32 choice = 2;
@@ -18075,7 +18049,7 @@ public int getChoice() {
      * required bytes lrs = 3;
      */
     public boolean hasLrs() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required bytes lrs = 3;
@@ -18110,13 +18084,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, pollid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeSInt32(2, choice_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, lrs_);
       }
       unknownFields.writeTo(output);
@@ -18128,15 +18102,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, pollid_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(2, choice_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, lrs_);
       }
@@ -18155,24 +18129,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.PollAnswer other = (ch.epfl.dedis.lib.proto.Personhood.PollAnswer) obj;
 
-      boolean result = true;
-      result = result && (hasPollid() == other.hasPollid());
+      if (hasPollid() != other.hasPollid()) return false;
       if (hasPollid()) {
-        result = result && getPollid()
-            .equals(other.getPollid());
+        if (!getPollid()
+            .equals(other.getPollid())) return false;
       }
-      result = result && (hasChoice() == other.hasChoice());
+      if (hasChoice() != other.hasChoice()) return false;
       if (hasChoice()) {
-        result = result && (getChoice()
-            == other.getChoice());
+        if (getChoice()
+            != other.getChoice()) return false;
       }
-      result = result && (hasLrs() == other.hasLrs());
+      if (hasLrs() != other.hasLrs()) return false;
       if (hasLrs()) {
-        result = result && getLrs()
-            .equals(other.getLrs());
+        if (!getLrs()
+            .equals(other.getLrs())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -18369,15 +18342,15 @@ public ch.epfl.dedis.lib.proto.Personhood.PollAnswer buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.PollAnswer result = new ch.epfl.dedis.lib.proto.Personhood.PollAnswer(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.pollid_ = pollid_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.choice_ = choice_;
           to_bitField0_ |= 0x00000002;
         }
-        result.choice_ = choice_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.lrs_ = lrs_;
@@ -18388,35 +18361,35 @@ public ch.epfl.dedis.lib.proto.Personhood.PollAnswer buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -18483,7 +18456,7 @@ public Builder mergeFrom(
        * required bytes pollid = 1;
        */
       public boolean hasPollid() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes pollid = 1;
@@ -18518,7 +18491,7 @@ public Builder clearPollid() {
        * required sint32 choice = 2;
        */
       public boolean hasChoice() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required sint32 choice = 2;
@@ -18550,7 +18523,7 @@ public Builder clearChoice() {
        * required bytes lrs = 3;
        */
       public boolean hasLrs() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required bytes lrs = 3;
@@ -18798,7 +18771,7 @@ private PollStruct(
             }
             case 42: {
               com.google.protobuf.ByteString bs = input.readBytes();
-              if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+              if (!((mutable_bitField0_ & 0x00000010) != 0)) {
                 choices_ = new com.google.protobuf.LazyStringArrayList();
                 mutable_bitField0_ |= 0x00000010;
               }
@@ -18806,7 +18779,7 @@ private PollStruct(
               break;
             }
             case 50: {
-              if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+              if (!((mutable_bitField0_ & 0x00000020) != 0)) {
                 chosen_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000020;
               }
@@ -18829,10 +18802,10 @@ private PollStruct(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((mutable_bitField0_ & 0x00000010) != 0)) {
           choices_ = choices_.getUnmodifiableView();
         }
-        if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+        if (((mutable_bitField0_ & 0x00000020) != 0)) {
           chosen_ = java.util.Collections.unmodifiableList(chosen_);
         }
         this.unknownFields = unknownFields.build();
@@ -18859,7 +18832,7 @@ private PollStruct(
      * required bytes personhood = 1;
      */
     public boolean hasPersonhood() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes personhood = 1;
@@ -18874,7 +18847,7 @@ public com.google.protobuf.ByteString getPersonhood() {
      * optional bytes pollid = 2;
      */
     public boolean hasPollid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * optional bytes pollid = 2;
@@ -18889,7 +18862,7 @@ public com.google.protobuf.ByteString getPollid() {
      * required string title = 3;
      */
     public boolean hasTitle() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required string title = 3;
@@ -18931,7 +18904,7 @@ public java.lang.String getTitle() {
      * required string description = 4;
      */
     public boolean hasDescription() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * required string description = 4;
@@ -19063,16 +19036,16 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, personhood_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, pollid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 3, title_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 4, description_);
       }
       for (int i = 0; i < choices_.size(); i++) {
@@ -19090,18 +19063,18 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, personhood_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, pollid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, title_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, description_);
       }
       {
@@ -19131,33 +19104,32 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.PollStruct other = (ch.epfl.dedis.lib.proto.Personhood.PollStruct) obj;
 
-      boolean result = true;
-      result = result && (hasPersonhood() == other.hasPersonhood());
+      if (hasPersonhood() != other.hasPersonhood()) return false;
       if (hasPersonhood()) {
-        result = result && getPersonhood()
-            .equals(other.getPersonhood());
+        if (!getPersonhood()
+            .equals(other.getPersonhood())) return false;
       }
-      result = result && (hasPollid() == other.hasPollid());
+      if (hasPollid() != other.hasPollid()) return false;
       if (hasPollid()) {
-        result = result && getPollid()
-            .equals(other.getPollid());
+        if (!getPollid()
+            .equals(other.getPollid())) return false;
       }
-      result = result && (hasTitle() == other.hasTitle());
+      if (hasTitle() != other.hasTitle()) return false;
       if (hasTitle()) {
-        result = result && getTitle()
-            .equals(other.getTitle());
+        if (!getTitle()
+            .equals(other.getTitle())) return false;
       }
-      result = result && (hasDescription() == other.hasDescription());
+      if (hasDescription() != other.hasDescription()) return false;
       if (hasDescription()) {
-        result = result && getDescription()
-            .equals(other.getDescription());
-      }
-      result = result && getChoicesList()
-          .equals(other.getChoicesList());
-      result = result && getChosenList()
-          .equals(other.getChosenList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+        if (!getDescription()
+            .equals(other.getDescription())) return false;
+      }
+      if (!getChoicesList()
+          .equals(other.getChoicesList())) return false;
+      if (!getChosenList()
+          .equals(other.getChosenList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -19373,29 +19345,29 @@ public ch.epfl.dedis.lib.proto.Personhood.PollStruct buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.PollStruct result = new ch.epfl.dedis.lib.proto.Personhood.PollStruct(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.personhood_ = personhood_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.pollid_ = pollid_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.title_ = title_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
           to_bitField0_ |= 0x00000008;
         }
         result.description_ = description_;
-        if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((bitField0_ & 0x00000010) != 0)) {
           choices_ = choices_.getUnmodifiableView();
           bitField0_ = (bitField0_ & ~0x00000010);
         }
         result.choices_ = choices_;
         if (chosenBuilder_ == null) {
-          if (((bitField0_ & 0x00000020) == 0x00000020)) {
+          if (((bitField0_ & 0x00000020) != 0)) {
             chosen_ = java.util.Collections.unmodifiableList(chosen_);
             bitField0_ = (bitField0_ & ~0x00000020);
           }
@@ -19410,35 +19382,35 @@ public ch.epfl.dedis.lib.proto.Personhood.PollStruct buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -19553,7 +19525,7 @@ public Builder mergeFrom(
        * required bytes personhood = 1;
        */
       public boolean hasPersonhood() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes personhood = 1;
@@ -19588,7 +19560,7 @@ public Builder clearPersonhood() {
        * optional bytes pollid = 2;
        */
       public boolean hasPollid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * optional bytes pollid = 2;
@@ -19623,7 +19595,7 @@ public Builder clearPollid() {
        * required string title = 3;
        */
       public boolean hasTitle() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required string title = 3;
@@ -19699,7 +19671,7 @@ public Builder setTitleBytes(
        * required string description = 4;
        */
       public boolean hasDescription() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * required string description = 4;
@@ -19772,7 +19744,7 @@ public Builder setDescriptionBytes(
 
       private com.google.protobuf.LazyStringList choices_ = com.google.protobuf.LazyStringArrayList.EMPTY;
       private void ensureChoicesIsMutable() {
-        if (!((bitField0_ & 0x00000010) == 0x00000010)) {
+        if (!((bitField0_ & 0x00000010) != 0)) {
           choices_ = new com.google.protobuf.LazyStringArrayList(choices_);
           bitField0_ |= 0x00000010;
          }
@@ -19866,7 +19838,7 @@ public Builder addChoicesBytes(
       private java.util.List chosen_ =
         java.util.Collections.emptyList();
       private void ensureChosenIsMutable() {
-        if (!((bitField0_ & 0x00000020) == 0x00000020)) {
+        if (!((bitField0_ & 0x00000020) != 0)) {
           chosen_ = new java.util.ArrayList(chosen_);
           bitField0_ |= 0x00000020;
          }
@@ -20095,7 +20067,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PollChoice.Builder addChosenBuilder(
           chosenBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.Personhood.PollChoice, ch.epfl.dedis.lib.proto.Personhood.PollChoice.Builder, ch.epfl.dedis.lib.proto.Personhood.PollChoiceOrBuilder>(
                   chosen_,
-                  ((bitField0_ & 0x00000020) == 0x00000020),
+                  ((bitField0_ & 0x00000020) != 0),
                   getParentForChildren(),
                   isClean());
           chosen_ = null;
@@ -20194,7 +20166,6 @@ private PollChoice(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private PollChoice() {
-      choice_ = 0;
       lrstag_ = com.google.protobuf.ByteString.EMPTY;
     }
 
@@ -20271,7 +20242,7 @@ private PollChoice(
      * required sint32 choice = 1;
      */
     public boolean hasChoice() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required sint32 choice = 1;
@@ -20286,7 +20257,7 @@ public int getChoice() {
      * required bytes lrstag = 2;
      */
     public boolean hasLrstag() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes lrstag = 2;
@@ -20317,10 +20288,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, choice_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, lrstag_);
       }
       unknownFields.writeTo(output);
@@ -20332,11 +20303,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, choice_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, lrstag_);
       }
@@ -20355,19 +20326,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.PollChoice other = (ch.epfl.dedis.lib.proto.Personhood.PollChoice) obj;
 
-      boolean result = true;
-      result = result && (hasChoice() == other.hasChoice());
+      if (hasChoice() != other.hasChoice()) return false;
       if (hasChoice()) {
-        result = result && (getChoice()
-            == other.getChoice());
+        if (getChoice()
+            != other.getChoice()) return false;
       }
-      result = result && (hasLrstag() == other.hasLrstag());
+      if (hasLrstag() != other.hasLrstag()) return false;
       if (hasLrstag()) {
-        result = result && getLrstag()
-            .equals(other.getLrstag());
+        if (!getLrstag()
+            .equals(other.getLrstag())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -20554,11 +20524,11 @@ public ch.epfl.dedis.lib.proto.Personhood.PollChoice buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.PollChoice result = new ch.epfl.dedis.lib.proto.Personhood.PollChoice(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.choice_ = choice_;
           to_bitField0_ |= 0x00000001;
         }
-        result.choice_ = choice_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.lrstag_ = lrstag_;
@@ -20569,35 +20539,35 @@ public ch.epfl.dedis.lib.proto.Personhood.PollChoice buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -20658,7 +20628,7 @@ public Builder mergeFrom(
        * required sint32 choice = 1;
        */
       public boolean hasChoice() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required sint32 choice = 1;
@@ -20690,7 +20660,7 @@ public Builder clearChoice() {
        * required bytes lrstag = 2;
        */
       public boolean hasLrstag() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes lrstag = 2;
@@ -20847,7 +20817,7 @@ private PollResponse(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 polls_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -20870,7 +20840,7 @@ private PollResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           polls_ = java.util.Collections.unmodifiableList(polls_);
         }
         this.unknownFields = unknownFields.build();
@@ -20976,11 +20946,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.PollResponse other = (ch.epfl.dedis.lib.proto.Personhood.PollResponse) obj;
 
-      boolean result = true;
-      result = result && getPollsList()
-          .equals(other.getPollsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getPollsList()
+          .equals(other.getPollsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -21168,7 +21137,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PollResponse buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.PollResponse result = new ch.epfl.dedis.lib.proto.Personhood.PollResponse(this);
         int from_bitField0_ = bitField0_;
         if (pollsBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             polls_ = java.util.Collections.unmodifiableList(polls_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -21182,35 +21151,35 @@ public ch.epfl.dedis.lib.proto.Personhood.PollResponse buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -21288,7 +21257,7 @@ public Builder mergeFrom(
       private java.util.List polls_ =
         java.util.Collections.emptyList();
       private void ensurePollsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           polls_ = new java.util.ArrayList(polls_);
           bitField0_ |= 0x00000001;
          }
@@ -21517,7 +21486,7 @@ public ch.epfl.dedis.lib.proto.Personhood.PollStruct.Builder addPollsBuilder(
           pollsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.Personhood.PollStruct, ch.epfl.dedis.lib.proto.Personhood.PollStruct.Builder, ch.epfl.dedis.lib.proto.Personhood.PollStructOrBuilder>(
                   polls_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           polls_ = null;
@@ -21693,9 +21662,8 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.Capabilities other = (ch.epfl.dedis.lib.proto.Personhood.Capabilities) obj;
 
-      boolean result = true;
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -21874,35 +21842,35 @@ public ch.epfl.dedis.lib.proto.Personhood.Capabilities buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -22077,7 +22045,7 @@ private CapabilitiesResponse(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 capabilities_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -22100,7 +22068,7 @@ private CapabilitiesResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           capabilities_ = java.util.Collections.unmodifiableList(capabilities_);
         }
         this.unknownFields = unknownFields.build();
@@ -22206,11 +22174,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.CapabilitiesResponse other = (ch.epfl.dedis.lib.proto.Personhood.CapabilitiesResponse) obj;
 
-      boolean result = true;
-      result = result && getCapabilitiesList()
-          .equals(other.getCapabilitiesList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getCapabilitiesList()
+          .equals(other.getCapabilitiesList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -22403,7 +22370,7 @@ public ch.epfl.dedis.lib.proto.Personhood.CapabilitiesResponse buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.CapabilitiesResponse result = new ch.epfl.dedis.lib.proto.Personhood.CapabilitiesResponse(this);
         int from_bitField0_ = bitField0_;
         if (capabilitiesBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             capabilities_ = java.util.Collections.unmodifiableList(capabilities_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -22417,35 +22384,35 @@ public ch.epfl.dedis.lib.proto.Personhood.CapabilitiesResponse buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -22523,7 +22490,7 @@ public Builder mergeFrom(
       private java.util.List capabilities_ =
         java.util.Collections.emptyList();
       private void ensureCapabilitiesIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           capabilities_ = new java.util.ArrayList(capabilities_);
           bitField0_ |= 0x00000001;
          }
@@ -22752,7 +22719,7 @@ public ch.epfl.dedis.lib.proto.Personhood.Capability.Builder addCapabilitiesBuil
           capabilitiesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.Personhood.Capability, ch.epfl.dedis.lib.proto.Personhood.Capability.Builder, ch.epfl.dedis.lib.proto.Personhood.CapabilityOrBuilder>(
                   capabilities_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           capabilities_ = null;
@@ -22934,7 +22901,7 @@ private Capability(
      * required string endpoint = 1;
      */
     public boolean hasEndpoint() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required string endpoint = 1;
@@ -22976,7 +22943,7 @@ public java.lang.String getEndpoint() {
      * required bytes version = 2;
      */
     public boolean hasVersion() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes version = 2;
@@ -23007,10 +22974,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, endpoint_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, version_);
       }
       unknownFields.writeTo(output);
@@ -23022,10 +22989,10 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, endpoint_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, version_);
       }
@@ -23044,19 +23011,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.Capability other = (ch.epfl.dedis.lib.proto.Personhood.Capability) obj;
 
-      boolean result = true;
-      result = result && (hasEndpoint() == other.hasEndpoint());
+      if (hasEndpoint() != other.hasEndpoint()) return false;
       if (hasEndpoint()) {
-        result = result && getEndpoint()
-            .equals(other.getEndpoint());
+        if (!getEndpoint()
+            .equals(other.getEndpoint())) return false;
       }
-      result = result && (hasVersion() == other.hasVersion());
+      if (hasVersion() != other.hasVersion()) return false;
       if (hasVersion()) {
-        result = result && getVersion()
-            .equals(other.getVersion());
+        if (!getVersion()
+            .equals(other.getVersion())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -23243,11 +23209,11 @@ public ch.epfl.dedis.lib.proto.Personhood.Capability buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.Capability result = new ch.epfl.dedis.lib.proto.Personhood.Capability(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.endpoint_ = endpoint_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.version_ = version_;
@@ -23258,35 +23224,35 @@ public ch.epfl.dedis.lib.proto.Personhood.Capability buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -23349,7 +23315,7 @@ public Builder mergeFrom(
        * required string endpoint = 1;
        */
       public boolean hasEndpoint() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required string endpoint = 1;
@@ -23425,7 +23391,7 @@ public Builder setEndpointBytes(
        * required bytes version = 2;
        */
       public boolean hasVersion() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes version = 2;
@@ -23585,7 +23551,6 @@ private UserLocation() {
       publickey_ = com.google.protobuf.ByteString.EMPTY;
       credentialiid_ = com.google.protobuf.ByteString.EMPTY;
       location_ = "";
-      time_ = 0L;
     }
 
     @java.lang.Override
@@ -23624,7 +23589,7 @@ private UserLocation(
             }
             case 26: {
               ch.epfl.dedis.lib.proto.Personhood.CredentialStruct.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (((bitField0_ & 0x00000004) != 0)) {
                 subBuilder = credential_.toBuilder();
               }
               credential_ = input.readMessage(ch.epfl.dedis.lib.proto.Personhood.CredentialStruct.parser(), extensionRegistry);
@@ -23685,7 +23650,7 @@ private UserLocation(
      * required bytes publickey = 1;
      */
     public boolean hasPublickey() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes publickey = 1;
@@ -23700,7 +23665,7 @@ public com.google.protobuf.ByteString getPublickey() {
      * optional bytes credentialiid = 2;
      */
     public boolean hasCredentialiid() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * optional bytes credentialiid = 2;
@@ -23715,7 +23680,7 @@ public com.google.protobuf.ByteString getCredentialiid() {
      * optional .personhood.CredentialStruct credential = 3;
      */
     public boolean hasCredential() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * optional .personhood.CredentialStruct credential = 3;
@@ -23736,7 +23701,7 @@ public ch.epfl.dedis.lib.proto.Personhood.CredentialStructOrBuilder getCredentia
      * optional string location = 4;
      */
     public boolean hasLocation() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * optional string location = 4;
@@ -23778,7 +23743,7 @@ public java.lang.String getLocation() {
      * required sint64 time = 5;
      */
     public boolean hasTime() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * required sint64 time = 5;
@@ -23815,19 +23780,19 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, publickey_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, credentialiid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeMessage(3, getCredential());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 4, location_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         output.writeSInt64(5, time_);
       }
       unknownFields.writeTo(output);
@@ -23839,22 +23804,22 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, publickey_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, credentialiid_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getCredential());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, location_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt64Size(5, time_);
       }
@@ -23873,34 +23838,33 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.UserLocation other = (ch.epfl.dedis.lib.proto.Personhood.UserLocation) obj;
 
-      boolean result = true;
-      result = result && (hasPublickey() == other.hasPublickey());
+      if (hasPublickey() != other.hasPublickey()) return false;
       if (hasPublickey()) {
-        result = result && getPublickey()
-            .equals(other.getPublickey());
+        if (!getPublickey()
+            .equals(other.getPublickey())) return false;
       }
-      result = result && (hasCredentialiid() == other.hasCredentialiid());
+      if (hasCredentialiid() != other.hasCredentialiid()) return false;
       if (hasCredentialiid()) {
-        result = result && getCredentialiid()
-            .equals(other.getCredentialiid());
+        if (!getCredentialiid()
+            .equals(other.getCredentialiid())) return false;
       }
-      result = result && (hasCredential() == other.hasCredential());
+      if (hasCredential() != other.hasCredential()) return false;
       if (hasCredential()) {
-        result = result && getCredential()
-            .equals(other.getCredential());
+        if (!getCredential()
+            .equals(other.getCredential())) return false;
       }
-      result = result && (hasLocation() == other.hasLocation());
+      if (hasLocation() != other.hasLocation()) return false;
       if (hasLocation()) {
-        result = result && getLocation()
-            .equals(other.getLocation());
+        if (!getLocation()
+            .equals(other.getLocation())) return false;
       }
-      result = result && (hasTime() == other.hasTime());
+      if (hasTime() != other.hasTime()) return false;
       if (hasTime()) {
-        result = result && (getTime()
-            == other.getTime());
+        if (getTime()
+            != other.getTime()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -24111,30 +24075,30 @@ public ch.epfl.dedis.lib.proto.Personhood.UserLocation buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.UserLocation result = new ch.epfl.dedis.lib.proto.Personhood.UserLocation(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.publickey_ = publickey_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.credentialiid_ = credentialiid_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          if (credentialBuilder_ == null) {
+            result.credential_ = credential_;
+          } else {
+            result.credential_ = credentialBuilder_.build();
+          }
           to_bitField0_ |= 0x00000004;
         }
-        if (credentialBuilder_ == null) {
-          result.credential_ = credential_;
-        } else {
-          result.credential_ = credentialBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
           to_bitField0_ |= 0x00000008;
         }
         result.location_ = location_;
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((from_bitField0_ & 0x00000010) != 0)) {
+          result.time_ = time_;
           to_bitField0_ |= 0x00000010;
         }
-        result.time_ = time_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -24142,35 +24106,35 @@ public ch.epfl.dedis.lib.proto.Personhood.UserLocation buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -24247,7 +24211,7 @@ public Builder mergeFrom(
        * required bytes publickey = 1;
        */
       public boolean hasPublickey() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes publickey = 1;
@@ -24282,7 +24246,7 @@ public Builder clearPublickey() {
        * optional bytes credentialiid = 2;
        */
       public boolean hasCredentialiid() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * optional bytes credentialiid = 2;
@@ -24312,14 +24276,14 @@ public Builder clearCredentialiid() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.Personhood.CredentialStruct credential_ = null;
+      private ch.epfl.dedis.lib.proto.Personhood.CredentialStruct credential_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.Personhood.CredentialStruct, ch.epfl.dedis.lib.proto.Personhood.CredentialStruct.Builder, ch.epfl.dedis.lib.proto.Personhood.CredentialStructOrBuilder> credentialBuilder_;
       /**
        * optional .personhood.CredentialStruct credential = 3;
        */
       public boolean hasCredential() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * optional .personhood.CredentialStruct credential = 3;
@@ -24366,7 +24330,7 @@ public Builder setCredential(
        */
       public Builder mergeCredential(ch.epfl.dedis.lib.proto.Personhood.CredentialStruct value) {
         if (credentialBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+          if (((bitField0_ & 0x00000004) != 0) &&
               credential_ != null &&
               credential_ != ch.epfl.dedis.lib.proto.Personhood.CredentialStruct.getDefaultInstance()) {
             credential_ =
@@ -24435,7 +24399,7 @@ public ch.epfl.dedis.lib.proto.Personhood.CredentialStructOrBuilder getCredentia
        * optional string location = 4;
        */
       public boolean hasLocation() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * optional string location = 4;
@@ -24511,7 +24475,7 @@ public Builder setLocationBytes(
        * required sint64 time = 5;
        */
       public boolean hasTime() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return ((bitField0_ & 0x00000010) != 0);
       }
       /**
        * required sint64 time = 5;
@@ -24633,7 +24597,6 @@ private Meetup(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private Meetup() {
-      wipe_ = false;
     }
 
     @java.lang.Override
@@ -24662,7 +24625,7 @@ private Meetup(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.Personhood.UserLocation.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = userlocation_.toBuilder();
               }
               userlocation_ = input.readMessage(ch.epfl.dedis.lib.proto.Personhood.UserLocation.parser(), extensionRegistry);
@@ -24717,7 +24680,7 @@ private Meetup(
      * optional .personhood.UserLocation userlocation = 1;
      */
     public boolean hasUserlocation() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * optional .personhood.UserLocation userlocation = 1;
@@ -24738,7 +24701,7 @@ public ch.epfl.dedis.lib.proto.Personhood.UserLocationOrBuilder getUserlocationO
      * optional bool wipe = 2;
      */
     public boolean hasWipe() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * optional bool wipe = 2;
@@ -24767,10 +24730,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getUserlocation());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBool(2, wipe_);
       }
       unknownFields.writeTo(output);
@@ -24782,11 +24745,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getUserlocation());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBoolSize(2, wipe_);
       }
@@ -24805,19 +24768,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.Meetup other = (ch.epfl.dedis.lib.proto.Personhood.Meetup) obj;
 
-      boolean result = true;
-      result = result && (hasUserlocation() == other.hasUserlocation());
+      if (hasUserlocation() != other.hasUserlocation()) return false;
       if (hasUserlocation()) {
-        result = result && getUserlocation()
-            .equals(other.getUserlocation());
+        if (!getUserlocation()
+            .equals(other.getUserlocation())) return false;
       }
-      result = result && (hasWipe() == other.hasWipe());
+      if (hasWipe() != other.hasWipe()) return false;
       if (hasWipe()) {
-        result = result && (getWipe()
-            == other.getWipe());
+        if (getWipe()
+            != other.getWipe()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -25010,18 +24972,18 @@ public ch.epfl.dedis.lib.proto.Personhood.Meetup buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.Meetup result = new ch.epfl.dedis.lib.proto.Personhood.Meetup(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (userlocationBuilder_ == null) {
+            result.userlocation_ = userlocation_;
+          } else {
+            result.userlocation_ = userlocationBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (userlocationBuilder_ == null) {
-          result.userlocation_ = userlocation_;
-        } else {
-          result.userlocation_ = userlocationBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.wipe_ = wipe_;
           to_bitField0_ |= 0x00000002;
         }
-        result.wipe_ = wipe_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -25029,35 +24991,35 @@ public ch.epfl.dedis.lib.proto.Personhood.Meetup buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -25112,14 +25074,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.Personhood.UserLocation userlocation_ = null;
+      private ch.epfl.dedis.lib.proto.Personhood.UserLocation userlocation_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.Personhood.UserLocation, ch.epfl.dedis.lib.proto.Personhood.UserLocation.Builder, ch.epfl.dedis.lib.proto.Personhood.UserLocationOrBuilder> userlocationBuilder_;
       /**
        * optional .personhood.UserLocation userlocation = 1;
        */
       public boolean hasUserlocation() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * optional .personhood.UserLocation userlocation = 1;
@@ -25166,7 +25128,7 @@ public Builder setUserlocation(
        */
       public Builder mergeUserlocation(ch.epfl.dedis.lib.proto.Personhood.UserLocation value) {
         if (userlocationBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               userlocation_ != null &&
               userlocation_ != ch.epfl.dedis.lib.proto.Personhood.UserLocation.getDefaultInstance()) {
             userlocation_ =
@@ -25235,7 +25197,7 @@ public ch.epfl.dedis.lib.proto.Personhood.UserLocationOrBuilder getUserlocationO
        * optional bool wipe = 2;
        */
       public boolean hasWipe() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * optional bool wipe = 2;
@@ -25387,7 +25349,7 @@ private MeetupResponse(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 users_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -25410,7 +25372,7 @@ private MeetupResponse(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           users_ = java.util.Collections.unmodifiableList(users_);
         }
         this.unknownFields = unknownFields.build();
@@ -25516,11 +25478,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.Personhood.MeetupResponse other = (ch.epfl.dedis.lib.proto.Personhood.MeetupResponse) obj;
 
-      boolean result = true;
-      result = result && getUsersList()
-          .equals(other.getUsersList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getUsersList()
+          .equals(other.getUsersList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -25706,7 +25667,7 @@ public ch.epfl.dedis.lib.proto.Personhood.MeetupResponse buildPartial() {
         ch.epfl.dedis.lib.proto.Personhood.MeetupResponse result = new ch.epfl.dedis.lib.proto.Personhood.MeetupResponse(this);
         int from_bitField0_ = bitField0_;
         if (usersBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             users_ = java.util.Collections.unmodifiableList(users_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -25720,35 +25681,35 @@ public ch.epfl.dedis.lib.proto.Personhood.MeetupResponse buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -25826,7 +25787,7 @@ public Builder mergeFrom(
       private java.util.List users_ =
         java.util.Collections.emptyList();
       private void ensureUsersIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           users_ = new java.util.ArrayList(users_);
           bitField0_ |= 0x00000001;
          }
@@ -26055,7 +26016,7 @@ public ch.epfl.dedis.lib.proto.Personhood.UserLocation.Builder addUsersBuilder(
           usersBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.Personhood.UserLocation, ch.epfl.dedis.lib.proto.Personhood.UserLocation.Builder, ch.epfl.dedis.lib.proto.Personhood.UserLocationOrBuilder>(
                   users_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           users_ = null;
diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/SkipchainProto.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/SkipchainProto.java
index c32d33035b..f1717227bc 100644
--- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/SkipchainProto.java
+++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/SkipchainProto.java
@@ -104,7 +104,7 @@ private StoreSkipBlock(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = newBlock_.toBuilder();
               }
               newBlock_ = input.readMessage(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.parser(), extensionRegistry);
@@ -159,7 +159,7 @@ private StoreSkipBlock(
      * required bytes targetSkipChainID = 1;
      */
     public boolean hasTargetSkipChainID() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes targetSkipChainID = 1;
@@ -174,7 +174,7 @@ public com.google.protobuf.ByteString getTargetSkipChainID() {
      * required .skipchain.SkipBlock newBlock = 2;
      */
     public boolean hasNewBlock() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required .skipchain.SkipBlock newBlock = 2;
@@ -195,7 +195,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder getNewBlockOrBu
      * optional bytes signature = 3;
      */
     public boolean hasSignature() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * optional bytes signature = 3;
@@ -230,13 +230,13 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, targetSkipChainID_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getNewBlock());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(3, signature_);
       }
       unknownFields.writeTo(output);
@@ -248,15 +248,15 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, targetSkipChainID_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getNewBlock());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, signature_);
       }
@@ -275,24 +275,23 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlock other = (ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlock) obj;
 
-      boolean result = true;
-      result = result && (hasTargetSkipChainID() == other.hasTargetSkipChainID());
+      if (hasTargetSkipChainID() != other.hasTargetSkipChainID()) return false;
       if (hasTargetSkipChainID()) {
-        result = result && getTargetSkipChainID()
-            .equals(other.getTargetSkipChainID());
+        if (!getTargetSkipChainID()
+            .equals(other.getTargetSkipChainID())) return false;
       }
-      result = result && (hasNewBlock() == other.hasNewBlock());
+      if (hasNewBlock() != other.hasNewBlock()) return false;
       if (hasNewBlock()) {
-        result = result && getNewBlock()
-            .equals(other.getNewBlock());
+        if (!getNewBlock()
+            .equals(other.getNewBlock())) return false;
       }
-      result = result && (hasSignature() == other.hasSignature());
+      if (hasSignature() != other.hasSignature()) return false;
       if (hasSignature()) {
-        result = result && getSignature()
-            .equals(other.getSignature());
+        if (!getSignature()
+            .equals(other.getSignature())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -493,19 +492,19 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlock buildPartial() {
         ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlock result = new ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlock(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.targetSkipChainID_ = targetSkipChainID_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (newBlockBuilder_ == null) {
+            result.newBlock_ = newBlock_;
+          } else {
+            result.newBlock_ = newBlockBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (newBlockBuilder_ == null) {
-          result.newBlock_ = newBlock_;
-        } else {
-          result.newBlock_ = newBlockBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.signature_ = signature_;
@@ -516,35 +515,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlock buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -611,7 +610,7 @@ public Builder mergeFrom(
        * required bytes targetSkipChainID = 1;
        */
       public boolean hasTargetSkipChainID() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes targetSkipChainID = 1;
@@ -641,14 +640,14 @@ public Builder clearTargetSkipChainID() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock newBlock_ = null;
+      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock newBlock_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder> newBlockBuilder_;
       /**
        * required .skipchain.SkipBlock newBlock = 2;
        */
       public boolean hasNewBlock() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required .skipchain.SkipBlock newBlock = 2;
@@ -695,7 +694,7 @@ public Builder setNewBlock(
        */
       public Builder mergeNewBlock(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock value) {
         if (newBlockBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               newBlock_ != null &&
               newBlock_ != ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.getDefaultInstance()) {
             newBlock_ =
@@ -764,7 +763,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder getNewBlockOrBu
        * optional bytes signature = 3;
        */
       public boolean hasSignature() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * optional bytes signature = 3;
@@ -922,7 +921,7 @@ private StoreSkipBlockReply(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = previous_.toBuilder();
               }
               previous_ = input.readMessage(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.parser(), extensionRegistry);
@@ -935,7 +934,7 @@ private StoreSkipBlockReply(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = latest_.toBuilder();
               }
               latest_ = input.readMessage(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.parser(), extensionRegistry);
@@ -985,7 +984,7 @@ private StoreSkipBlockReply(
      * optional .skipchain.SkipBlock previous = 1;
      */
     public boolean hasPrevious() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * optional .skipchain.SkipBlock previous = 1;
@@ -1006,7 +1005,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder getPreviousOrBu
      * required .skipchain.SkipBlock latest = 2;
      */
     public boolean hasLatest() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required .skipchain.SkipBlock latest = 2;
@@ -1049,10 +1048,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getPrevious());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(2, getLatest());
       }
       unknownFields.writeTo(output);
@@ -1064,11 +1063,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getPrevious());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getLatest());
       }
@@ -1087,19 +1086,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlockReply other = (ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlockReply) obj;
 
-      boolean result = true;
-      result = result && (hasPrevious() == other.hasPrevious());
+      if (hasPrevious() != other.hasPrevious()) return false;
       if (hasPrevious()) {
-        result = result && getPrevious()
-            .equals(other.getPrevious());
+        if (!getPrevious()
+            .equals(other.getPrevious())) return false;
       }
-      result = result && (hasLatest() == other.hasLatest());
+      if (hasLatest() != other.hasLatest()) return false;
       if (hasLatest()) {
-        result = result && getLatest()
-            .equals(other.getLatest());
+        if (!getLatest()
+            .equals(other.getLatest())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -1297,22 +1295,22 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlockReply buildPartial()
         ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlockReply result = new ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlockReply(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (previousBuilder_ == null) {
+            result.previous_ = previous_;
+          } else {
+            result.previous_ = previousBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (previousBuilder_ == null) {
-          result.previous_ = previous_;
-        } else {
-          result.previous_ = previousBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (latestBuilder_ == null) {
+            result.latest_ = latest_;
+          } else {
+            result.latest_ = latestBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (latestBuilder_ == null) {
-          result.latest_ = latest_;
-        } else {
-          result.latest_ = latestBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -1320,35 +1318,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.StoreSkipBlockReply buildPartial()
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -1409,14 +1407,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock previous_ = null;
+      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock previous_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder> previousBuilder_;
       /**
        * optional .skipchain.SkipBlock previous = 1;
        */
       public boolean hasPrevious() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * optional .skipchain.SkipBlock previous = 1;
@@ -1463,7 +1461,7 @@ public Builder setPrevious(
        */
       public Builder mergePrevious(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock value) {
         if (previousBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               previous_ != null &&
               previous_ != ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.getDefaultInstance()) {
             previous_ =
@@ -1527,14 +1525,14 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder getPreviousOrBu
         return previousBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock latest_ = null;
+      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock latest_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder> latestBuilder_;
       /**
        * required .skipchain.SkipBlock latest = 2;
        */
       public boolean hasLatest() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required .skipchain.SkipBlock latest = 2;
@@ -1581,7 +1579,7 @@ public Builder setLatest(
        */
       public Builder mergeLatest(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock value) {
         if (latestBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               latest_ != null &&
               latest_ != ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.getDefaultInstance()) {
             latest_ =
@@ -1814,9 +1812,8 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.GetAllSkipChainIDs other = (ch.epfl.dedis.lib.proto.SkipchainProto.GetAllSkipChainIDs) obj;
 
-      boolean result = true;
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -1996,35 +1993,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetAllSkipChainIDs buildPartial()
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -2181,7 +2178,7 @@ private GetAllSkipChainIDsReply(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 skipChainIDs_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -2203,8 +2200,8 @@ private GetAllSkipChainIDsReply(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-          skipChainIDs_ = java.util.Collections.unmodifiableList(skipChainIDs_);
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          skipChainIDs_ = java.util.Collections.unmodifiableList(skipChainIDs_); // C
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -2295,11 +2292,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.GetAllSkipChainIDsReply other = (ch.epfl.dedis.lib.proto.SkipchainProto.GetAllSkipChainIDsReply) obj;
 
-      boolean result = true;
-      result = result && getSkipChainIDsList()
-          .equals(other.getSkipChainIDsList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getSkipChainIDsList()
+          .equals(other.getSkipChainIDsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -2479,7 +2475,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetAllSkipChainIDsReply build() {
       public ch.epfl.dedis.lib.proto.SkipchainProto.GetAllSkipChainIDsReply buildPartial() {
         ch.epfl.dedis.lib.proto.SkipchainProto.GetAllSkipChainIDsReply result = new ch.epfl.dedis.lib.proto.SkipchainProto.GetAllSkipChainIDsReply(this);
         int from_bitField0_ = bitField0_;
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((bitField0_ & 0x00000001) != 0)) {
           skipChainIDs_ = java.util.Collections.unmodifiableList(skipChainIDs_);
           bitField0_ = (bitField0_ & ~0x00000001);
         }
@@ -2490,35 +2486,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetAllSkipChainIDsReply buildParti
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -2574,7 +2570,7 @@ public Builder mergeFrom(
 
       private java.util.List skipChainIDs_ = java.util.Collections.emptyList();
       private void ensureSkipChainIDsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           skipChainIDs_ = new java.util.ArrayList(skipChainIDs_);
           bitField0_ |= 0x00000001;
          }
@@ -2584,7 +2580,8 @@ private void ensureSkipChainIDsIsMutable() {
        */
       public java.util.List
           getSkipChainIDsList() {
-        return java.util.Collections.unmodifiableList(skipChainIDs_);
+        return ((bitField0_ & 0x00000001) != 0) ?
+                 java.util.Collections.unmodifiableList(skipChainIDs_) : skipChainIDs_;
       }
       /**
        * repeated bytes skipChainIDs = 1;
@@ -2797,7 +2794,7 @@ private GetSingleBlock(
      * required bytes id = 1;
      */
     public boolean hasId() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes id = 1;
@@ -2824,7 +2821,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, id_);
       }
       unknownFields.writeTo(output);
@@ -2836,7 +2833,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, id_);
       }
@@ -2855,14 +2852,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlock other = (ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlock) obj;
 
-      boolean result = true;
-      result = result && (hasId() == other.hasId());
+      if (hasId() != other.hasId()) return false;
       if (hasId()) {
-        result = result && getId()
-            .equals(other.getId());
+        if (!getId()
+            .equals(other.getId())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -3043,7 +3039,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlock buildPartial() {
         ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlock result = new ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlock(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.id_ = id_;
@@ -3054,35 +3050,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlock buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -3137,7 +3133,7 @@ public Builder mergeFrom(
        * required bytes id = 1;
        */
       public boolean hasId() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes id = 1;
@@ -3260,7 +3256,6 @@ private GetSingleBlockByIndex(com.google.protobuf.GeneratedMessageV3.Builder
     }
     private GetSingleBlockByIndex() {
       genesis_ = com.google.protobuf.ByteString.EMPTY;
-      index_ = 0;
     }
 
     @java.lang.Override
@@ -3336,7 +3331,7 @@ private GetSingleBlockByIndex(
      * required bytes genesis = 1;
      */
     public boolean hasGenesis() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes genesis = 1;
@@ -3351,7 +3346,7 @@ public com.google.protobuf.ByteString getGenesis() {
      * required sint32 index = 2;
      */
     public boolean hasIndex() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required sint32 index = 2;
@@ -3382,10 +3377,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, genesis_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeSInt32(2, index_);
       }
       unknownFields.writeTo(output);
@@ -3397,11 +3392,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, genesis_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(2, index_);
       }
@@ -3420,19 +3415,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndex other = (ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndex) obj;
 
-      boolean result = true;
-      result = result && (hasGenesis() == other.hasGenesis());
+      if (hasGenesis() != other.hasGenesis()) return false;
       if (hasGenesis()) {
-        result = result && getGenesis()
-            .equals(other.getGenesis());
+        if (!getGenesis()
+            .equals(other.getGenesis())) return false;
       }
-      result = result && (hasIndex() == other.hasIndex());
+      if (hasIndex() != other.hasIndex()) return false;
       if (hasIndex()) {
-        result = result && (getIndex()
-            == other.getIndex());
+        if (getIndex()
+            != other.getIndex()) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -3620,14 +3614,14 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndex buildPartial
         ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndex result = new ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndex(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.genesis_ = genesis_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.index_ = index_;
           to_bitField0_ |= 0x00000002;
         }
-        result.index_ = index_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -3635,35 +3629,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndex buildPartial
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -3724,7 +3718,7 @@ public Builder mergeFrom(
        * required bytes genesis = 1;
        */
       public boolean hasGenesis() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes genesis = 1;
@@ -3759,7 +3753,7 @@ public Builder clearGenesis() {
        * required sint32 index = 2;
        */
       public boolean hasIndex() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required sint32 index = 2;
@@ -3926,7 +3920,7 @@ private GetSingleBlockByIndexReply(
               break;
             case 10: {
               ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = skipblock_.toBuilder();
               }
               skipblock_ = input.readMessage(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.parser(), extensionRegistry);
@@ -3938,7 +3932,7 @@ private GetSingleBlockByIndexReply(
               break;
             }
             case 18: {
-              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
                 links_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000002;
               }
@@ -3961,7 +3955,7 @@ private GetSingleBlockByIndexReply(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
           links_ = java.util.Collections.unmodifiableList(links_);
         }
         this.unknownFields = unknownFields.build();
@@ -3988,7 +3982,7 @@ private GetSingleBlockByIndexReply(
      * required .skipchain.SkipBlock skipblock = 1;
      */
     public boolean hasSkipblock() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required .skipchain.SkipBlock skipblock = 1;
@@ -4066,7 +4060,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(1, getSkipblock());
       }
       for (int i = 0; i < links_.size(); i++) {
@@ -4081,7 +4075,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getSkipblock());
       }
@@ -4104,16 +4098,15 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndexReply other = (ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndexReply) obj;
 
-      boolean result = true;
-      result = result && (hasSkipblock() == other.hasSkipblock());
+      if (hasSkipblock() != other.hasSkipblock()) return false;
       if (hasSkipblock()) {
-        result = result && getSkipblock()
-            .equals(other.getSkipblock());
+        if (!getSkipblock()
+            .equals(other.getSkipblock())) return false;
       }
-      result = result && getLinksList()
-          .equals(other.getLinksList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getLinksList()
+          .equals(other.getLinksList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -4311,16 +4304,16 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndexReply buildPa
         ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndexReply result = new ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndexReply(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (skipblockBuilder_ == null) {
+            result.skipblock_ = skipblock_;
+          } else {
+            result.skipblock_ = skipblockBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (skipblockBuilder_ == null) {
-          result.skipblock_ = skipblock_;
-        } else {
-          result.skipblock_ = skipblockBuilder_.build();
-        }
         if (linksBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          if (((bitField0_ & 0x00000002) != 0)) {
             links_ = java.util.Collections.unmodifiableList(links_);
             bitField0_ = (bitField0_ & ~0x00000002);
           }
@@ -4335,35 +4328,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetSingleBlockByIndexReply buildPa
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -4447,14 +4440,14 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock skipblock_ = null;
+      private ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock skipblock_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder> skipblockBuilder_;
       /**
        * required .skipchain.SkipBlock skipblock = 1;
        */
       public boolean hasSkipblock() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required .skipchain.SkipBlock skipblock = 1;
@@ -4501,7 +4494,7 @@ public Builder setSkipblock(
        */
       public Builder mergeSkipblock(ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock value) {
         if (skipblockBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+          if (((bitField0_ & 0x00000001) != 0) &&
               skipblock_ != null &&
               skipblock_ != ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.getDefaultInstance()) {
             skipblock_ =
@@ -4568,7 +4561,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder getSkipblockOrB
       private java.util.List links_ =
         java.util.Collections.emptyList();
       private void ensureLinksIsMutable() {
-        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+        if (!((bitField0_ & 0x00000002) != 0)) {
           links_ = new java.util.ArrayList(links_);
           bitField0_ |= 0x00000002;
          }
@@ -4797,7 +4790,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink.Builder addLinksBuilde
           linksBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink, ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLinkOrBuilder>(
                   links_,
-                  ((bitField0_ & 0x00000002) == 0x00000002),
+                  ((bitField0_ & 0x00000002) != 0),
                   getParentForChildren(),
                   isClean());
           links_ = null;
@@ -4972,7 +4965,7 @@ private GetUpdateChain(
      * required bytes latestID = 1;
      */
     public boolean hasLatestID() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * 
@@ -5003,7 +4996,7 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, latestID_);
       }
       unknownFields.writeTo(output);
@@ -5015,7 +5008,7 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, latestID_);
       }
@@ -5034,14 +5027,13 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChain other = (ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChain) obj;
 
-      boolean result = true;
-      result = result && (hasLatestID() == other.hasLatestID());
+      if (hasLatestID() != other.hasLatestID()) return false;
       if (hasLatestID()) {
-        result = result && getLatestID()
-            .equals(other.getLatestID());
+        if (!getLatestID()
+            .equals(other.getLatestID())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -5224,7 +5216,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChain buildPartial() {
         ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChain result = new ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChain(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.latestID_ = latestID_;
@@ -5235,35 +5227,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChain buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -5322,7 +5314,7 @@ public Builder mergeFrom(
        * required bytes latestID = 1;
        */
       public boolean hasLatestID() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * 
@@ -5515,7 +5507,7 @@ private GetUpdateChainReply(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 update_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -5538,7 +5530,7 @@ private GetUpdateChainReply(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           update_ = java.util.Collections.unmodifiableList(update_);
         }
         this.unknownFields = unknownFields.build();
@@ -5669,11 +5661,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChainReply other = (ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChainReply) obj;
 
-      boolean result = true;
-      result = result && getUpdateList()
-          .equals(other.getUpdateList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getUpdateList()
+          .equals(other.getUpdateList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -5860,7 +5851,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChainReply buildPartial()
         ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChainReply result = new ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChainReply(this);
         int from_bitField0_ = bitField0_;
         if (updateBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             update_ = java.util.Collections.unmodifiableList(update_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -5874,35 +5865,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.GetUpdateChainReply buildPartial()
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -5980,7 +5971,7 @@ public Builder mergeFrom(
       private java.util.List update_ =
         java.util.Collections.emptyList();
       private void ensureUpdateIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           update_ = new java.util.ArrayList(update_);
           bitField0_ |= 0x00000001;
          }
@@ -6299,7 +6290,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder addUpdateBuilder
           updateBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlockOrBuilder>(
                   update_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           update_ = null;
@@ -6511,10 +6502,6 @@ private SkipBlock(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private SkipBlock() {
-      index_ = 0;
-      height_ = 0;
-      maxHeight_ = 0;
-      baseHeight_ = 0;
       backlinks_ = java.util.Collections.emptyList();
       verifiers_ = java.util.Collections.emptyList();
       genesis_ = com.google.protobuf.ByteString.EMPTY;
@@ -6569,7 +6556,7 @@ private SkipBlock(
               break;
             }
             case 42: {
-              if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+              if (!((mutable_bitField0_ & 0x00000010) != 0)) {
                 backlinks_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000010;
               }
@@ -6577,7 +6564,7 @@ private SkipBlock(
               break;
             }
             case 50: {
-              if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
+              if (!((mutable_bitField0_ & 0x00000020) != 0)) {
                 verifiers_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000020;
               }
@@ -6596,7 +6583,7 @@ private SkipBlock(
             }
             case 74: {
               ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000040) == 0x00000040)) {
+              if (((bitField0_ & 0x00000040) != 0)) {
                 subBuilder = roster_.toBuilder();
               }
               roster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry);
@@ -6613,7 +6600,7 @@ private SkipBlock(
               break;
             }
             case 90: {
-              if (!((mutable_bitField0_ & 0x00000400) == 0x00000400)) {
+              if (!((mutable_bitField0_ & 0x00000400) != 0)) {
                 forward_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000400;
               }
@@ -6641,13 +6628,13 @@ private SkipBlock(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
-          backlinks_ = java.util.Collections.unmodifiableList(backlinks_);
+        if (((mutable_bitField0_ & 0x00000010) != 0)) {
+          backlinks_ = java.util.Collections.unmodifiableList(backlinks_); // C
         }
-        if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
-          verifiers_ = java.util.Collections.unmodifiableList(verifiers_);
+        if (((mutable_bitField0_ & 0x00000020) != 0)) {
+          verifiers_ = java.util.Collections.unmodifiableList(verifiers_); // C
         }
-        if (((mutable_bitField0_ & 0x00000400) == 0x00000400)) {
+        if (((mutable_bitField0_ & 0x00000400) != 0)) {
           forward_ = java.util.Collections.unmodifiableList(forward_);
         }
         this.unknownFields = unknownFields.build();
@@ -6674,7 +6661,7 @@ private SkipBlock(
      * required sint32 index = 1;
      */
     public boolean hasIndex() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required sint32 index = 1;
@@ -6689,7 +6676,7 @@ public int getIndex() {
      * required sint32 height = 2;
      */
     public boolean hasHeight() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required sint32 height = 2;
@@ -6704,7 +6691,7 @@ public int getHeight() {
      * required sint32 max_height = 3;
      */
     public boolean hasMaxHeight() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required sint32 max_height = 3;
@@ -6719,7 +6706,7 @@ public int getMaxHeight() {
      * required sint32 base_height = 4;
      */
     public boolean hasBaseHeight() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * required sint32 base_height = 4;
@@ -6778,7 +6765,7 @@ public com.google.protobuf.ByteString getVerifiers(int index) {
      * required bytes genesis = 7;
      */
     public boolean hasGenesis() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return ((bitField0_ & 0x00000010) != 0);
     }
     /**
      * required bytes genesis = 7;
@@ -6793,7 +6780,7 @@ public com.google.protobuf.ByteString getGenesis() {
      * required bytes data = 8;
      */
     public boolean hasData() {
-      return ((bitField0_ & 0x00000020) == 0x00000020);
+      return ((bitField0_ & 0x00000020) != 0);
     }
     /**
      * required bytes data = 8;
@@ -6808,7 +6795,7 @@ public com.google.protobuf.ByteString getData() {
      * required .onet.Roster roster = 9;
      */
     public boolean hasRoster() {
-      return ((bitField0_ & 0x00000040) == 0x00000040);
+      return ((bitField0_ & 0x00000040) != 0);
     }
     /**
      * required .onet.Roster roster = 9;
@@ -6829,7 +6816,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() {
      * required bytes hash = 10;
      */
     public boolean hasHash() {
-      return ((bitField0_ & 0x00000080) == 0x00000080);
+      return ((bitField0_ & 0x00000080) != 0);
     }
     /**
      * required bytes hash = 10;
@@ -6879,7 +6866,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLinkOrBuilder getForwardOrB
      * optional bytes payload = 12;
      */
     public boolean hasPayload() {
-      return ((bitField0_ & 0x00000100) == 0x00000100);
+      return ((bitField0_ & 0x00000100) != 0);
     }
     /**
      * optional bytes payload = 12;
@@ -6944,16 +6931,16 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, index_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeSInt32(2, height_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeSInt32(3, maxHeight_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeSInt32(4, baseHeight_);
       }
       for (int i = 0; i < backlinks_.size(); i++) {
@@ -6962,22 +6949,22 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
       for (int i = 0; i < verifiers_.size(); i++) {
         output.writeBytes(6, verifiers_.get(i));
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         output.writeBytes(7, genesis_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         output.writeBytes(8, data_);
       }
-      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+      if (((bitField0_ & 0x00000040) != 0)) {
         output.writeMessage(9, getRoster());
       }
-      if (((bitField0_ & 0x00000080) == 0x00000080)) {
+      if (((bitField0_ & 0x00000080) != 0)) {
         output.writeBytes(10, hash_);
       }
       for (int i = 0; i < forward_.size(); i++) {
         output.writeMessage(11, forward_.get(i));
       }
-      if (((bitField0_ & 0x00000100) == 0x00000100)) {
+      if (((bitField0_ & 0x00000100) != 0)) {
         output.writeBytes(12, payload_);
       }
       unknownFields.writeTo(output);
@@ -6989,19 +6976,19 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, index_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(2, height_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(3, maxHeight_);
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(4, baseHeight_);
       }
@@ -7023,19 +7010,19 @@ public int getSerializedSize() {
         size += dataSize;
         size += 1 * getVerifiersList().size();
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (((bitField0_ & 0x00000010) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(7, genesis_);
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (((bitField0_ & 0x00000020) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(8, data_);
       }
-      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+      if (((bitField0_ & 0x00000040) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(9, getRoster());
       }
-      if (((bitField0_ & 0x00000080) == 0x00000080)) {
+      if (((bitField0_ & 0x00000080) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(10, hash_);
       }
@@ -7043,7 +7030,7 @@ public int getSerializedSize() {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(11, forward_.get(i));
       }
-      if (((bitField0_ & 0x00000100) == 0x00000100)) {
+      if (((bitField0_ & 0x00000100) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(12, payload_);
       }
@@ -7062,60 +7049,59 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock other = (ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock) obj;
 
-      boolean result = true;
-      result = result && (hasIndex() == other.hasIndex());
+      if (hasIndex() != other.hasIndex()) return false;
       if (hasIndex()) {
-        result = result && (getIndex()
-            == other.getIndex());
+        if (getIndex()
+            != other.getIndex()) return false;
       }
-      result = result && (hasHeight() == other.hasHeight());
+      if (hasHeight() != other.hasHeight()) return false;
       if (hasHeight()) {
-        result = result && (getHeight()
-            == other.getHeight());
+        if (getHeight()
+            != other.getHeight()) return false;
       }
-      result = result && (hasMaxHeight() == other.hasMaxHeight());
+      if (hasMaxHeight() != other.hasMaxHeight()) return false;
       if (hasMaxHeight()) {
-        result = result && (getMaxHeight()
-            == other.getMaxHeight());
+        if (getMaxHeight()
+            != other.getMaxHeight()) return false;
       }
-      result = result && (hasBaseHeight() == other.hasBaseHeight());
+      if (hasBaseHeight() != other.hasBaseHeight()) return false;
       if (hasBaseHeight()) {
-        result = result && (getBaseHeight()
-            == other.getBaseHeight());
-      }
-      result = result && getBacklinksList()
-          .equals(other.getBacklinksList());
-      result = result && getVerifiersList()
-          .equals(other.getVerifiersList());
-      result = result && (hasGenesis() == other.hasGenesis());
+        if (getBaseHeight()
+            != other.getBaseHeight()) return false;
+      }
+      if (!getBacklinksList()
+          .equals(other.getBacklinksList())) return false;
+      if (!getVerifiersList()
+          .equals(other.getVerifiersList())) return false;
+      if (hasGenesis() != other.hasGenesis()) return false;
       if (hasGenesis()) {
-        result = result && getGenesis()
-            .equals(other.getGenesis());
+        if (!getGenesis()
+            .equals(other.getGenesis())) return false;
       }
-      result = result && (hasData() == other.hasData());
+      if (hasData() != other.hasData()) return false;
       if (hasData()) {
-        result = result && getData()
-            .equals(other.getData());
+        if (!getData()
+            .equals(other.getData())) return false;
       }
-      result = result && (hasRoster() == other.hasRoster());
+      if (hasRoster() != other.hasRoster()) return false;
       if (hasRoster()) {
-        result = result && getRoster()
-            .equals(other.getRoster());
+        if (!getRoster()
+            .equals(other.getRoster())) return false;
       }
-      result = result && (hasHash() == other.hasHash());
+      if (hasHash() != other.hasHash()) return false;
       if (hasHash()) {
-        result = result && getHash()
-            .equals(other.getHash());
+        if (!getHash()
+            .equals(other.getHash())) return false;
       }
-      result = result && getForwardList()
-          .equals(other.getForwardList());
-      result = result && (hasPayload() == other.hasPayload());
+      if (!getForwardList()
+          .equals(other.getForwardList())) return false;
+      if (hasPayload() != other.hasPayload()) return false;
       if (hasPayload()) {
-        result = result && getPayload()
-            .equals(other.getPayload());
+        if (!getPayload()
+            .equals(other.getPayload())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -7368,54 +7354,54 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock buildPartial() {
         ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock result = new ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.index_ = index_;
           to_bitField0_ |= 0x00000001;
         }
-        result.index_ = index_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          result.height_ = height_;
           to_bitField0_ |= 0x00000002;
         }
-        result.height_ = height_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          result.maxHeight_ = maxHeight_;
           to_bitField0_ |= 0x00000004;
         }
-        result.maxHeight_ = maxHeight_;
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          result.baseHeight_ = baseHeight_;
           to_bitField0_ |= 0x00000008;
         }
-        result.baseHeight_ = baseHeight_;
-        if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        if (((bitField0_ & 0x00000010) != 0)) {
           backlinks_ = java.util.Collections.unmodifiableList(backlinks_);
           bitField0_ = (bitField0_ & ~0x00000010);
         }
         result.backlinks_ = backlinks_;
-        if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        if (((bitField0_ & 0x00000020) != 0)) {
           verifiers_ = java.util.Collections.unmodifiableList(verifiers_);
           bitField0_ = (bitField0_ & ~0x00000020);
         }
         result.verifiers_ = verifiers_;
-        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
+        if (((from_bitField0_ & 0x00000040) != 0)) {
           to_bitField0_ |= 0x00000010;
         }
         result.genesis_ = genesis_;
-        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
+        if (((from_bitField0_ & 0x00000080) != 0)) {
           to_bitField0_ |= 0x00000020;
         }
         result.data_ = data_;
-        if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
+        if (((from_bitField0_ & 0x00000100) != 0)) {
+          if (rosterBuilder_ == null) {
+            result.roster_ = roster_;
+          } else {
+            result.roster_ = rosterBuilder_.build();
+          }
           to_bitField0_ |= 0x00000040;
         }
-        if (rosterBuilder_ == null) {
-          result.roster_ = roster_;
-        } else {
-          result.roster_ = rosterBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000200) == 0x00000200)) {
+        if (((from_bitField0_ & 0x00000200) != 0)) {
           to_bitField0_ |= 0x00000080;
         }
         result.hash_ = hash_;
         if (forwardBuilder_ == null) {
-          if (((bitField0_ & 0x00000400) == 0x00000400)) {
+          if (((bitField0_ & 0x00000400) != 0)) {
             forward_ = java.util.Collections.unmodifiableList(forward_);
             bitField0_ = (bitField0_ & ~0x00000400);
           }
@@ -7423,7 +7409,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock buildPartial() {
         } else {
           result.forward_ = forwardBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000800) == 0x00000800)) {
+        if (((from_bitField0_ & 0x00000800) != 0)) {
           to_bitField0_ |= 0x00000100;
         }
         result.payload_ = payload_;
@@ -7434,35 +7420,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SkipBlock buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -7616,7 +7602,7 @@ public Builder mergeFrom(
        * required sint32 index = 1;
        */
       public boolean hasIndex() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required sint32 index = 1;
@@ -7648,7 +7634,7 @@ public Builder clearIndex() {
        * required sint32 height = 2;
        */
       public boolean hasHeight() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required sint32 height = 2;
@@ -7680,7 +7666,7 @@ public Builder clearHeight() {
        * required sint32 max_height = 3;
        */
       public boolean hasMaxHeight() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required sint32 max_height = 3;
@@ -7712,7 +7698,7 @@ public Builder clearMaxHeight() {
        * required sint32 base_height = 4;
        */
       public boolean hasBaseHeight() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * required sint32 base_height = 4;
@@ -7741,7 +7727,7 @@ public Builder clearBaseHeight() {
 
       private java.util.List backlinks_ = java.util.Collections.emptyList();
       private void ensureBacklinksIsMutable() {
-        if (!((bitField0_ & 0x00000010) == 0x00000010)) {
+        if (!((bitField0_ & 0x00000010) != 0)) {
           backlinks_ = new java.util.ArrayList(backlinks_);
           bitField0_ |= 0x00000010;
          }
@@ -7751,7 +7737,8 @@ private void ensureBacklinksIsMutable() {
        */
       public java.util.List
           getBacklinksList() {
-        return java.util.Collections.unmodifiableList(backlinks_);
+        return ((bitField0_ & 0x00000010) != 0) ?
+                 java.util.Collections.unmodifiableList(backlinks_) : backlinks_;
       }
       /**
        * repeated bytes backlinks = 5;
@@ -7813,7 +7800,7 @@ public Builder clearBacklinks() {
 
       private java.util.List verifiers_ = java.util.Collections.emptyList();
       private void ensureVerifiersIsMutable() {
-        if (!((bitField0_ & 0x00000020) == 0x00000020)) {
+        if (!((bitField0_ & 0x00000020) != 0)) {
           verifiers_ = new java.util.ArrayList(verifiers_);
           bitField0_ |= 0x00000020;
          }
@@ -7823,7 +7810,8 @@ private void ensureVerifiersIsMutable() {
        */
       public java.util.List
           getVerifiersList() {
-        return java.util.Collections.unmodifiableList(verifiers_);
+        return ((bitField0_ & 0x00000020) != 0) ?
+                 java.util.Collections.unmodifiableList(verifiers_) : verifiers_;
       }
       /**
        * repeated bytes verifiers = 6;
@@ -7888,7 +7876,7 @@ public Builder clearVerifiers() {
        * required bytes genesis = 7;
        */
       public boolean hasGenesis() {
-        return ((bitField0_ & 0x00000040) == 0x00000040);
+        return ((bitField0_ & 0x00000040) != 0);
       }
       /**
        * required bytes genesis = 7;
@@ -7923,7 +7911,7 @@ public Builder clearGenesis() {
        * required bytes data = 8;
        */
       public boolean hasData() {
-        return ((bitField0_ & 0x00000080) == 0x00000080);
+        return ((bitField0_ & 0x00000080) != 0);
       }
       /**
        * required bytes data = 8;
@@ -7953,14 +7941,14 @@ public Builder clearData() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_ = null;
+      private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> rosterBuilder_;
       /**
        * required .onet.Roster roster = 9;
        */
       public boolean hasRoster() {
-        return ((bitField0_ & 0x00000100) == 0x00000100);
+        return ((bitField0_ & 0x00000100) != 0);
       }
       /**
        * required .onet.Roster roster = 9;
@@ -8007,7 +7995,7 @@ public Builder setRoster(
        */
       public Builder mergeRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) {
         if (rosterBuilder_ == null) {
-          if (((bitField0_ & 0x00000100) == 0x00000100) &&
+          if (((bitField0_ & 0x00000100) != 0) &&
               roster_ != null &&
               roster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) {
             roster_ =
@@ -8076,7 +8064,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() {
        * required bytes hash = 10;
        */
       public boolean hasHash() {
-        return ((bitField0_ & 0x00000200) == 0x00000200);
+        return ((bitField0_ & 0x00000200) != 0);
       }
       /**
        * required bytes hash = 10;
@@ -8109,7 +8097,7 @@ public Builder clearHash() {
       private java.util.List forward_ =
         java.util.Collections.emptyList();
       private void ensureForwardIsMutable() {
-        if (!((bitField0_ & 0x00000400) == 0x00000400)) {
+        if (!((bitField0_ & 0x00000400) != 0)) {
           forward_ = new java.util.ArrayList(forward_);
           bitField0_ |= 0x00000400;
          }
@@ -8338,7 +8326,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink.Builder addForwardBuil
           forwardBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink, ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLinkOrBuilder>(
                   forward_,
-                  ((bitField0_ & 0x00000400) == 0x00000400),
+                  ((bitField0_ & 0x00000400) != 0),
                   getParentForChildren(),
                   isClean());
           forward_ = null;
@@ -8351,7 +8339,7 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink.Builder addForwardBuil
        * optional bytes payload = 12;
        */
       public boolean hasPayload() {
-        return ((bitField0_ & 0x00000800) == 0x00000800);
+        return ((bitField0_ & 0x00000800) != 0);
       }
       /**
        * optional bytes payload = 12;
@@ -8534,7 +8522,7 @@ private ForwardLink(
             }
             case 26: {
               ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (((bitField0_ & 0x00000004) != 0)) {
                 subBuilder = newRoster_.toBuilder();
               }
               newRoster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry);
@@ -8547,7 +8535,7 @@ private ForwardLink(
             }
             case 34: {
               ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000008) == 0x00000008)) {
+              if (((bitField0_ & 0x00000008) != 0)) {
                 subBuilder = signature_.toBuilder();
               }
               signature_ = input.readMessage(ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig.parser(), extensionRegistry);
@@ -8597,7 +8585,7 @@ private ForwardLink(
      * required bytes from = 1;
      */
     public boolean hasFrom() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes from = 1;
@@ -8612,7 +8600,7 @@ public com.google.protobuf.ByteString getFrom() {
      * required bytes to = 2;
      */
     public boolean hasTo() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes to = 2;
@@ -8627,7 +8615,7 @@ public com.google.protobuf.ByteString getTo() {
      * optional .onet.Roster newRoster = 3;
      */
     public boolean hasNewRoster() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * optional .onet.Roster newRoster = 3;
@@ -8648,7 +8636,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getNewRosterOrBuilder()
      * required .skipchain.ByzcoinSig signature = 4;
      */
     public boolean hasSignature() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return ((bitField0_ & 0x00000008) != 0);
     }
     /**
      * required .skipchain.ByzcoinSig signature = 4;
@@ -8699,16 +8687,16 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, from_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, to_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeMessage(3, getNewRoster());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         output.writeMessage(4, getSignature());
       }
       unknownFields.writeTo(output);
@@ -8720,19 +8708,19 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, from_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, to_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getNewRoster());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (((bitField0_ & 0x00000008) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(4, getSignature());
       }
@@ -8751,29 +8739,28 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink other = (ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink) obj;
 
-      boolean result = true;
-      result = result && (hasFrom() == other.hasFrom());
+      if (hasFrom() != other.hasFrom()) return false;
       if (hasFrom()) {
-        result = result && getFrom()
-            .equals(other.getFrom());
+        if (!getFrom()
+            .equals(other.getFrom())) return false;
       }
-      result = result && (hasTo() == other.hasTo());
+      if (hasTo() != other.hasTo()) return false;
       if (hasTo()) {
-        result = result && getTo()
-            .equals(other.getTo());
+        if (!getTo()
+            .equals(other.getTo())) return false;
       }
-      result = result && (hasNewRoster() == other.hasNewRoster());
+      if (hasNewRoster() != other.hasNewRoster()) return false;
       if (hasNewRoster()) {
-        result = result && getNewRoster()
-            .equals(other.getNewRoster());
+        if (!getNewRoster()
+            .equals(other.getNewRoster())) return false;
       }
-      result = result && (hasSignature() == other.hasSignature());
+      if (hasSignature() != other.hasSignature()) return false;
       if (hasSignature()) {
-        result = result && getSignature()
-            .equals(other.getSignature());
+        if (!getSignature()
+            .equals(other.getSignature())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -8978,30 +8965,30 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink buildPartial() {
         ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink result = new ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.from_ = from_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.to_ = to_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          if (newRosterBuilder_ == null) {
+            result.newRoster_ = newRoster_;
+          } else {
+            result.newRoster_ = newRosterBuilder_.build();
+          }
           to_bitField0_ |= 0x00000004;
         }
-        if (newRosterBuilder_ == null) {
-          result.newRoster_ = newRoster_;
-        } else {
-          result.newRoster_ = newRosterBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
+          if (signatureBuilder_ == null) {
+            result.signature_ = signature_;
+          } else {
+            result.signature_ = signatureBuilder_.build();
+          }
           to_bitField0_ |= 0x00000008;
         }
-        if (signatureBuilder_ == null) {
-          result.signature_ = signature_;
-        } else {
-          result.signature_ = signatureBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -9009,35 +8996,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.ForwardLink buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -9115,7 +9102,7 @@ public Builder mergeFrom(
        * required bytes from = 1;
        */
       public boolean hasFrom() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes from = 1;
@@ -9150,7 +9137,7 @@ public Builder clearFrom() {
        * required bytes to = 2;
        */
       public boolean hasTo() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes to = 2;
@@ -9180,14 +9167,14 @@ public Builder clearTo() {
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.OnetProto.Roster newRoster_ = null;
+      private ch.epfl.dedis.lib.proto.OnetProto.Roster newRoster_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> newRosterBuilder_;
       /**
        * optional .onet.Roster newRoster = 3;
        */
       public boolean hasNewRoster() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * optional .onet.Roster newRoster = 3;
@@ -9234,7 +9221,7 @@ public Builder setNewRoster(
        */
       public Builder mergeNewRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) {
         if (newRosterBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+          if (((bitField0_ & 0x00000004) != 0) &&
               newRoster_ != null &&
               newRoster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) {
             newRoster_ =
@@ -9298,14 +9285,14 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getNewRosterOrBuilder()
         return newRosterBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig signature_ = null;
+      private ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig signature_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig, ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig.Builder, ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSigOrBuilder> signatureBuilder_;
       /**
        * required .skipchain.ByzcoinSig signature = 4;
        */
       public boolean hasSignature() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * required .skipchain.ByzcoinSig signature = 4;
@@ -9352,7 +9339,7 @@ public Builder setSignature(
        */
       public Builder mergeSignature(ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig value) {
         if (signatureBuilder_ == null) {
-          if (((bitField0_ & 0x00000008) == 0x00000008) &&
+          if (((bitField0_ & 0x00000008) != 0) &&
               signature_ != null &&
               signature_ != ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig.getDefaultInstance()) {
             signature_ =
@@ -9580,7 +9567,7 @@ private ByzcoinSig(
      * required bytes msg = 1;
      */
     public boolean hasMsg() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes msg = 1;
@@ -9595,7 +9582,7 @@ public com.google.protobuf.ByteString getMsg() {
      * required bytes sig = 2;
      */
     public boolean hasSig() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes sig = 2;
@@ -9626,10 +9613,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, msg_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, sig_);
       }
       unknownFields.writeTo(output);
@@ -9641,11 +9628,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, msg_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, sig_);
       }
@@ -9664,19 +9651,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig other = (ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig) obj;
 
-      boolean result = true;
-      result = result && (hasMsg() == other.hasMsg());
+      if (hasMsg() != other.hasMsg()) return false;
       if (hasMsg()) {
-        result = result && getMsg()
-            .equals(other.getMsg());
+        if (!getMsg()
+            .equals(other.getMsg())) return false;
       }
-      result = result && (hasSig() == other.hasSig());
+      if (hasSig() != other.hasSig()) return false;
       if (hasSig()) {
-        result = result && getSig()
-            .equals(other.getSig());
+        if (!getSig()
+            .equals(other.getSig())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -9859,11 +9845,11 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig buildPartial() {
         ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig result = new ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.msg_ = msg_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.sig_ = sig_;
@@ -9874,35 +9860,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.ByzcoinSig buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -9963,7 +9949,7 @@ public Builder mergeFrom(
        * required bytes msg = 1;
        */
       public boolean hasMsg() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes msg = 1;
@@ -9998,7 +9984,7 @@ public Builder clearMsg() {
        * required bytes sig = 2;
        */
       public boolean hasSig() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes sig = 2;
@@ -10192,7 +10178,7 @@ private SchnorrSig(
      * required bytes challenge = 1;
      */
     public boolean hasChallenge() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes challenge = 1;
@@ -10207,7 +10193,7 @@ public com.google.protobuf.ByteString getChallenge() {
      * required bytes response = 2;
      */
     public boolean hasResponse() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes response = 2;
@@ -10238,10 +10224,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, challenge_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, response_);
       }
       unknownFields.writeTo(output);
@@ -10253,11 +10239,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, challenge_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, response_);
       }
@@ -10276,19 +10262,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.SchnorrSig other = (ch.epfl.dedis.lib.proto.SkipchainProto.SchnorrSig) obj;
 
-      boolean result = true;
-      result = result && (hasChallenge() == other.hasChallenge());
+      if (hasChallenge() != other.hasChallenge()) return false;
       if (hasChallenge()) {
-        result = result && getChallenge()
-            .equals(other.getChallenge());
+        if (!getChallenge()
+            .equals(other.getChallenge())) return false;
       }
-      result = result && (hasResponse() == other.hasResponse());
+      if (hasResponse() != other.hasResponse()) return false;
       if (hasResponse()) {
-        result = result && getResponse()
-            .equals(other.getResponse());
+        if (!getResponse()
+            .equals(other.getResponse())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -10471,11 +10456,11 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SchnorrSig buildPartial() {
         ch.epfl.dedis.lib.proto.SkipchainProto.SchnorrSig result = new ch.epfl.dedis.lib.proto.SkipchainProto.SchnorrSig(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.challenge_ = challenge_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.response_ = response_;
@@ -10486,35 +10471,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.SchnorrSig buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -10575,7 +10560,7 @@ public Builder mergeFrom(
        * required bytes challenge = 1;
        */
       public boolean hasChallenge() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes challenge = 1;
@@ -10610,7 +10595,7 @@ public Builder clearChallenge() {
        * required bytes response = 2;
        */
       public boolean hasResponse() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes response = 2;
@@ -10727,7 +10712,6 @@ private Exception(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private Exception() {
-      index_ = 0;
       commitment_ = com.google.protobuf.ByteString.EMPTY;
     }
 
@@ -10804,7 +10788,7 @@ private Exception(
      * required sint32 index = 1;
      */
     public boolean hasIndex() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required sint32 index = 1;
@@ -10819,7 +10803,7 @@ public int getIndex() {
      * required bytes commitment = 2;
      */
     public boolean hasCommitment() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes commitment = 2;
@@ -10850,10 +10834,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeSInt32(1, index_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, commitment_);
       }
       unknownFields.writeTo(output);
@@ -10865,11 +10849,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeSInt32Size(1, index_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, commitment_);
       }
@@ -10888,19 +10872,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.SkipchainProto.Exception other = (ch.epfl.dedis.lib.proto.SkipchainProto.Exception) obj;
 
-      boolean result = true;
-      result = result && (hasIndex() == other.hasIndex());
+      if (hasIndex() != other.hasIndex()) return false;
       if (hasIndex()) {
-        result = result && (getIndex()
-            == other.getIndex());
+        if (getIndex()
+            != other.getIndex()) return false;
       }
-      result = result && (hasCommitment() == other.hasCommitment());
+      if (hasCommitment() != other.hasCommitment()) return false;
       if (hasCommitment()) {
-        result = result && getCommitment()
-            .equals(other.getCommitment());
+        if (!getCommitment()
+            .equals(other.getCommitment())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -11083,11 +11066,11 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.Exception buildPartial() {
         ch.epfl.dedis.lib.proto.SkipchainProto.Exception result = new ch.epfl.dedis.lib.proto.SkipchainProto.Exception(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          result.index_ = index_;
           to_bitField0_ |= 0x00000001;
         }
-        result.index_ = index_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.commitment_ = commitment_;
@@ -11098,35 +11081,35 @@ public ch.epfl.dedis.lib.proto.SkipchainProto.Exception buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -11187,7 +11170,7 @@ public Builder mergeFrom(
        * required sint32 index = 1;
        */
       public boolean hasIndex() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required sint32 index = 1;
@@ -11219,7 +11202,7 @@ public Builder clearIndex() {
        * required bytes commitment = 2;
        */
       public boolean hasCommitment() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes commitment = 2;
diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/StatusProto.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/StatusProto.java
index 15fd7f4fdf..f2ce7b0c36 100644
--- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/StatusProto.java
+++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/StatusProto.java
@@ -130,9 +130,8 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.StatusProto.Request other = (ch.epfl.dedis.lib.proto.StatusProto.Request) obj;
 
-      boolean result = true;
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -311,35 +310,35 @@ public ch.epfl.dedis.lib.proto.StatusProto.Request buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -529,7 +528,7 @@ private Response(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 status_ = com.google.protobuf.MapField.newMapField(
                     StatusDefaultEntryHolder.defaultEntry);
                 mutable_bitField0_ |= 0x00000001;
@@ -543,7 +542,7 @@ private Response(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = serveridentity_.toBuilder();
               }
               serveridentity_ = input.readMessage(ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity.parser(), extensionRegistry);
@@ -681,7 +680,7 @@ public ch.epfl.dedis.lib.proto.OnetProto.Status getStatusOrThrow(
      * optional .network.ServerIdentity serveridentity = 2;
      */
     public boolean hasServeridentity() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * optional .network.ServerIdentity serveridentity = 2;
@@ -722,7 +721,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
           internalGetStatus(),
           StatusDefaultEntryHolder.defaultEntry,
           1);
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(2, getServeridentity());
       }
       unknownFields.writeTo(output);
@@ -744,7 +743,7 @@ public int getSerializedSize() {
         size += com.google.protobuf.CodedOutputStream
             .computeMessageSize(1, status__);
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getServeridentity());
       }
@@ -763,16 +762,15 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.StatusProto.Response other = (ch.epfl.dedis.lib.proto.StatusProto.Response) obj;
 
-      boolean result = true;
-      result = result && internalGetStatus().equals(
-          other.internalGetStatus());
-      result = result && (hasServeridentity() == other.hasServeridentity());
+      if (!internalGetStatus().equals(
+          other.internalGetStatus())) return false;
+      if (hasServeridentity() != other.hasServeridentity()) return false;
       if (hasServeridentity()) {
-        result = result && getServeridentity()
-            .equals(other.getServeridentity());
+        if (!getServeridentity()
+            .equals(other.getServeridentity())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -987,14 +985,14 @@ public ch.epfl.dedis.lib.proto.StatusProto.Response buildPartial() {
         int to_bitField0_ = 0;
         result.status_ = internalGetStatus();
         result.status_.makeImmutable();
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (serveridentityBuilder_ == null) {
+            result.serveridentity_ = serveridentity_;
+          } else {
+            result.serveridentity_ = serveridentityBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (serveridentityBuilder_ == null) {
-          result.serveridentity_ = serveridentity_;
-        } else {
-          result.serveridentity_ = serveridentityBuilder_.build();
-        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -1002,35 +1000,35 @@ public ch.epfl.dedis.lib.proto.StatusProto.Response buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -1207,14 +1205,14 @@ public Builder putAllStatus(
         return this;
       }
 
-      private ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity serveridentity_ = null;
+      private ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity serveridentity_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity, ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity.Builder, ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentityOrBuilder> serveridentityBuilder_;
       /**
        * optional .network.ServerIdentity serveridentity = 2;
        */
       public boolean hasServeridentity() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * optional .network.ServerIdentity serveridentity = 2;
@@ -1261,7 +1259,7 @@ public Builder setServeridentity(
        */
       public Builder mergeServeridentity(ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity value) {
         if (serveridentityBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               serveridentity_ != null &&
               serveridentity_ != ch.epfl.dedis.lib.proto.NetworkProto.ServerIdentity.getDefaultInstance()) {
             serveridentity_ =
diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/TrieProto.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/TrieProto.java
index 1bc9b9b4e2..f81f398f4a 100644
--- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/TrieProto.java
+++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/TrieProto.java
@@ -126,7 +126,7 @@ private InteriorNode(
      * required bytes left = 1;
      */
     public boolean hasLeft() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes left = 1;
@@ -141,7 +141,7 @@ public com.google.protobuf.ByteString getLeft() {
      * required bytes right = 2;
      */
     public boolean hasRight() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes right = 2;
@@ -172,10 +172,10 @@ public final boolean isInitialized() {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(1, left_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(2, right_);
       }
       unknownFields.writeTo(output);
@@ -187,11 +187,11 @@ public int getSerializedSize() {
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(1, left_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, right_);
       }
@@ -210,19 +210,18 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.TrieProto.InteriorNode other = (ch.epfl.dedis.lib.proto.TrieProto.InteriorNode) obj;
 
-      boolean result = true;
-      result = result && (hasLeft() == other.hasLeft());
+      if (hasLeft() != other.hasLeft()) return false;
       if (hasLeft()) {
-        result = result && getLeft()
-            .equals(other.getLeft());
+        if (!getLeft()
+            .equals(other.getLeft())) return false;
       }
-      result = result && (hasRight() == other.hasRight());
+      if (hasRight() != other.hasRight()) return false;
       if (hasRight()) {
-        result = result && getRight()
-            .equals(other.getRight());
+        if (!getRight()
+            .equals(other.getRight())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -405,11 +404,11 @@ public ch.epfl.dedis.lib.proto.TrieProto.InteriorNode buildPartial() {
         ch.epfl.dedis.lib.proto.TrieProto.InteriorNode result = new ch.epfl.dedis.lib.proto.TrieProto.InteriorNode(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.left_ = left_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.right_ = right_;
@@ -420,35 +419,35 @@ public ch.epfl.dedis.lib.proto.TrieProto.InteriorNode buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -509,7 +508,7 @@ public Builder mergeFrom(
        * required bytes left = 1;
        */
       public boolean hasLeft() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
+        return ((bitField0_ & 0x00000001) != 0);
       }
       /**
        * required bytes left = 1;
@@ -544,7 +543,7 @@ public Builder clearLeft() {
        * required bytes right = 2;
        */
       public boolean hasRight() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes right = 2;
@@ -656,7 +655,7 @@ private EmptyNode(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private EmptyNode() {
-      prefix_ = java.util.Collections.emptyList();
+      prefix_ = emptyBooleanList();
     }
 
     @java.lang.Override
@@ -684,22 +683,22 @@ private EmptyNode(
               done = true;
               break;
             case 8: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-                prefix_ = new java.util.ArrayList();
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                prefix_ = newBooleanList();
                 mutable_bitField0_ |= 0x00000001;
               }
-              prefix_.add(input.readBool());
+              prefix_.addBoolean(input.readBool());
               break;
             }
             case 10: {
               int length = input.readRawVarint32();
               int limit = input.pushLimit(length);
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001) && input.getBytesUntilLimit() > 0) {
-                prefix_ = new java.util.ArrayList();
+              if (!((mutable_bitField0_ & 0x00000001) != 0) && input.getBytesUntilLimit() > 0) {
+                prefix_ = newBooleanList();
                 mutable_bitField0_ |= 0x00000001;
               }
               while (input.getBytesUntilLimit() > 0) {
-                prefix_.add(input.readBool());
+                prefix_.addBoolean(input.readBool());
               }
               input.popLimit(limit);
               break;
@@ -719,8 +718,8 @@ private EmptyNode(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-          prefix_ = java.util.Collections.unmodifiableList(prefix_);
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          prefix_.makeImmutable(); // C
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -740,7 +739,7 @@ private EmptyNode(
     }
 
     public static final int PREFIX_FIELD_NUMBER = 1;
-    private java.util.List prefix_;
+    private com.google.protobuf.Internal.BooleanList prefix_;
     /**
      * repeated bool prefix = 1 [packed = true];
      */
@@ -758,7 +757,7 @@ public int getPrefixCount() {
      * repeated bool prefix = 1 [packed = true];
      */
     public boolean getPrefix(int index) {
-      return prefix_.get(index);
+      return prefix_.getBoolean(index);
     }
     private int prefixMemoizedSerializedSize = -1;
 
@@ -782,7 +781,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
         output.writeUInt32NoTag(prefixMemoizedSerializedSize);
       }
       for (int i = 0; i < prefix_.size(); i++) {
-        output.writeBoolNoTag(prefix_.get(i));
+        output.writeBoolNoTag(prefix_.getBoolean(i));
       }
       unknownFields.writeTo(output);
     }
@@ -819,11 +818,10 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.TrieProto.EmptyNode other = (ch.epfl.dedis.lib.proto.TrieProto.EmptyNode) obj;
 
-      boolean result = true;
-      result = result && getPrefixList()
-          .equals(other.getPrefixList());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!getPrefixList()
+          .equals(other.getPrefixList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -970,7 +968,7 @@ private void maybeForceBuilderInitialization() {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        prefix_ = java.util.Collections.emptyList();
+        prefix_ = emptyBooleanList();
         bitField0_ = (bitField0_ & ~0x00000001);
         return this;
       }
@@ -999,8 +997,8 @@ public ch.epfl.dedis.lib.proto.TrieProto.EmptyNode build() {
       public ch.epfl.dedis.lib.proto.TrieProto.EmptyNode buildPartial() {
         ch.epfl.dedis.lib.proto.TrieProto.EmptyNode result = new ch.epfl.dedis.lib.proto.TrieProto.EmptyNode(this);
         int from_bitField0_ = bitField0_;
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
-          prefix_ = java.util.Collections.unmodifiableList(prefix_);
+        if (((bitField0_ & 0x00000001) != 0)) {
+          prefix_.makeImmutable();
           bitField0_ = (bitField0_ & ~0x00000001);
         }
         result.prefix_ = prefix_;
@@ -1010,35 +1008,35 @@ public ch.epfl.dedis.lib.proto.TrieProto.EmptyNode buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -1092,10 +1090,10 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private java.util.List prefix_ = java.util.Collections.emptyList();
+      private com.google.protobuf.Internal.BooleanList prefix_ = emptyBooleanList();
       private void ensurePrefixIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
-          prefix_ = new java.util.ArrayList(prefix_);
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          prefix_ = mutableCopy(prefix_);
           bitField0_ |= 0x00000001;
          }
       }
@@ -1104,7 +1102,8 @@ private void ensurePrefixIsMutable() {
        */
       public java.util.List
           getPrefixList() {
-        return java.util.Collections.unmodifiableList(prefix_);
+        return ((bitField0_ & 0x00000001) != 0) ?
+                 java.util.Collections.unmodifiableList(prefix_) : prefix_;
       }
       /**
        * repeated bool prefix = 1 [packed = true];
@@ -1116,7 +1115,7 @@ public int getPrefixCount() {
        * repeated bool prefix = 1 [packed = true];
        */
       public boolean getPrefix(int index) {
-        return prefix_.get(index);
+        return prefix_.getBoolean(index);
       }
       /**
        * repeated bool prefix = 1 [packed = true];
@@ -1124,7 +1123,7 @@ public boolean getPrefix(int index) {
       public Builder setPrefix(
           int index, boolean value) {
         ensurePrefixIsMutable();
-        prefix_.set(index, value);
+        prefix_.setBoolean(index, value);
         onChanged();
         return this;
       }
@@ -1133,7 +1132,7 @@ public Builder setPrefix(
        */
       public Builder addPrefix(boolean value) {
         ensurePrefixIsMutable();
-        prefix_.add(value);
+        prefix_.addBoolean(value);
         onChanged();
         return this;
       }
@@ -1152,7 +1151,7 @@ public Builder addAllPrefix(
        * repeated bool prefix = 1 [packed = true];
        */
       public Builder clearPrefix() {
-        prefix_ = java.util.Collections.emptyList();
+        prefix_ = emptyBooleanList();
         bitField0_ = (bitField0_ & ~0x00000001);
         onChanged();
         return this;
@@ -1258,7 +1257,7 @@ private LeafNode(com.google.protobuf.GeneratedMessageV3.Builder builder) {
       super(builder);
     }
     private LeafNode() {
-      prefix_ = java.util.Collections.emptyList();
+      prefix_ = emptyBooleanList();
       key_ = com.google.protobuf.ByteString.EMPTY;
       value_ = com.google.protobuf.ByteString.EMPTY;
     }
@@ -1288,22 +1287,22 @@ private LeafNode(
               done = true;
               break;
             case 8: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-                prefix_ = new java.util.ArrayList();
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                prefix_ = newBooleanList();
                 mutable_bitField0_ |= 0x00000001;
               }
-              prefix_.add(input.readBool());
+              prefix_.addBoolean(input.readBool());
               break;
             }
             case 10: {
               int length = input.readRawVarint32();
               int limit = input.pushLimit(length);
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001) && input.getBytesUntilLimit() > 0) {
-                prefix_ = new java.util.ArrayList();
+              if (!((mutable_bitField0_ & 0x00000001) != 0) && input.getBytesUntilLimit() > 0) {
+                prefix_ = newBooleanList();
                 mutable_bitField0_ |= 0x00000001;
               }
               while (input.getBytesUntilLimit() > 0) {
-                prefix_.add(input.readBool());
+                prefix_.addBoolean(input.readBool());
               }
               input.popLimit(limit);
               break;
@@ -1333,8 +1332,8 @@ private LeafNode(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-          prefix_ = java.util.Collections.unmodifiableList(prefix_);
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          prefix_.makeImmutable(); // C
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -1355,7 +1354,7 @@ private LeafNode(
 
     private int bitField0_;
     public static final int PREFIX_FIELD_NUMBER = 1;
-    private java.util.List prefix_;
+    private com.google.protobuf.Internal.BooleanList prefix_;
     /**
      * repeated bool prefix = 1 [packed = true];
      */
@@ -1373,7 +1372,7 @@ public int getPrefixCount() {
      * repeated bool prefix = 1 [packed = true];
      */
     public boolean getPrefix(int index) {
-      return prefix_.get(index);
+      return prefix_.getBoolean(index);
     }
     private int prefixMemoizedSerializedSize = -1;
 
@@ -1383,7 +1382,7 @@ public boolean getPrefix(int index) {
      * required bytes key = 2;
      */
     public boolean hasKey() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required bytes key = 2;
@@ -1398,7 +1397,7 @@ public com.google.protobuf.ByteString getKey() {
      * required bytes value = 3;
      */
     public boolean hasValue() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required bytes value = 3;
@@ -1435,12 +1434,12 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
         output.writeUInt32NoTag(prefixMemoizedSerializedSize);
       }
       for (int i = 0; i < prefix_.size(); i++) {
-        output.writeBoolNoTag(prefix_.get(i));
+        output.writeBoolNoTag(prefix_.getBoolean(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeBytes(2, key_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeBytes(3, value_);
       }
       unknownFields.writeTo(output);
@@ -1463,11 +1462,11 @@ public int getSerializedSize() {
         }
         prefixMemoizedSerializedSize = dataSize;
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(2, key_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(3, value_);
       }
@@ -1486,21 +1485,20 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.TrieProto.LeafNode other = (ch.epfl.dedis.lib.proto.TrieProto.LeafNode) obj;
 
-      boolean result = true;
-      result = result && getPrefixList()
-          .equals(other.getPrefixList());
-      result = result && (hasKey() == other.hasKey());
+      if (!getPrefixList()
+          .equals(other.getPrefixList())) return false;
+      if (hasKey() != other.hasKey()) return false;
       if (hasKey()) {
-        result = result && getKey()
-            .equals(other.getKey());
+        if (!getKey()
+            .equals(other.getKey())) return false;
       }
-      result = result && (hasValue() == other.hasValue());
+      if (hasValue() != other.hasValue()) return false;
       if (hasValue()) {
-        result = result && getValue()
-            .equals(other.getValue());
+        if (!getValue()
+            .equals(other.getValue())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -1655,7 +1653,7 @@ private void maybeForceBuilderInitialization() {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        prefix_ = java.util.Collections.emptyList();
+        prefix_ = emptyBooleanList();
         bitField0_ = (bitField0_ & ~0x00000001);
         key_ = com.google.protobuf.ByteString.EMPTY;
         bitField0_ = (bitField0_ & ~0x00000002);
@@ -1689,16 +1687,16 @@ public ch.epfl.dedis.lib.proto.TrieProto.LeafNode buildPartial() {
         ch.epfl.dedis.lib.proto.TrieProto.LeafNode result = new ch.epfl.dedis.lib.proto.TrieProto.LeafNode(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
-          prefix_ = java.util.Collections.unmodifiableList(prefix_);
+        if (((bitField0_ & 0x00000001) != 0)) {
+          prefix_.makeImmutable();
           bitField0_ = (bitField0_ & ~0x00000001);
         }
         result.prefix_ = prefix_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
           to_bitField0_ |= 0x00000001;
         }
         result.key_ = key_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
           to_bitField0_ |= 0x00000002;
         }
         result.value_ = value_;
@@ -1709,35 +1707,35 @@ public ch.epfl.dedis.lib.proto.TrieProto.LeafNode buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -1803,10 +1801,10 @@ public Builder mergeFrom(
       }
       private int bitField0_;
 
-      private java.util.List prefix_ = java.util.Collections.emptyList();
+      private com.google.protobuf.Internal.BooleanList prefix_ = emptyBooleanList();
       private void ensurePrefixIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
-          prefix_ = new java.util.ArrayList(prefix_);
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          prefix_ = mutableCopy(prefix_);
           bitField0_ |= 0x00000001;
          }
       }
@@ -1815,7 +1813,8 @@ private void ensurePrefixIsMutable() {
        */
       public java.util.List
           getPrefixList() {
-        return java.util.Collections.unmodifiableList(prefix_);
+        return ((bitField0_ & 0x00000001) != 0) ?
+                 java.util.Collections.unmodifiableList(prefix_) : prefix_;
       }
       /**
        * repeated bool prefix = 1 [packed = true];
@@ -1827,7 +1826,7 @@ public int getPrefixCount() {
        * repeated bool prefix = 1 [packed = true];
        */
       public boolean getPrefix(int index) {
-        return prefix_.get(index);
+        return prefix_.getBoolean(index);
       }
       /**
        * repeated bool prefix = 1 [packed = true];
@@ -1835,7 +1834,7 @@ public boolean getPrefix(int index) {
       public Builder setPrefix(
           int index, boolean value) {
         ensurePrefixIsMutable();
-        prefix_.set(index, value);
+        prefix_.setBoolean(index, value);
         onChanged();
         return this;
       }
@@ -1844,7 +1843,7 @@ public Builder setPrefix(
        */
       public Builder addPrefix(boolean value) {
         ensurePrefixIsMutable();
-        prefix_.add(value);
+        prefix_.addBoolean(value);
         onChanged();
         return this;
       }
@@ -1863,7 +1862,7 @@ public Builder addAllPrefix(
        * repeated bool prefix = 1 [packed = true];
        */
       public Builder clearPrefix() {
-        prefix_ = java.util.Collections.emptyList();
+        prefix_ = emptyBooleanList();
         bitField0_ = (bitField0_ & ~0x00000001);
         onChanged();
         return this;
@@ -1874,7 +1873,7 @@ public Builder clearPrefix() {
        * required bytes key = 2;
        */
       public boolean hasKey() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required bytes key = 2;
@@ -1909,7 +1908,7 @@ public Builder clearKey() {
        * required bytes value = 3;
        */
       public boolean hasValue() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required bytes value = 3;
@@ -2100,7 +2099,7 @@ private Proof(
               done = true;
               break;
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                 interiors_ = new java.util.ArrayList();
                 mutable_bitField0_ |= 0x00000001;
               }
@@ -2110,7 +2109,7 @@ private Proof(
             }
             case 18: {
               ch.epfl.dedis.lib.proto.TrieProto.LeafNode.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (((bitField0_ & 0x00000001) != 0)) {
                 subBuilder = leaf_.toBuilder();
               }
               leaf_ = input.readMessage(ch.epfl.dedis.lib.proto.TrieProto.LeafNode.parser(), extensionRegistry);
@@ -2123,7 +2122,7 @@ private Proof(
             }
             case 26: {
               ch.epfl.dedis.lib.proto.TrieProto.EmptyNode.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (((bitField0_ & 0x00000002) != 0)) {
                 subBuilder = empty_.toBuilder();
               }
               empty_ = input.readMessage(ch.epfl.dedis.lib.proto.TrieProto.EmptyNode.parser(), extensionRegistry);
@@ -2154,7 +2153,7 @@ private Proof(
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
           interiors_ = java.util.Collections.unmodifiableList(interiors_);
         }
         this.unknownFields = unknownFields.build();
@@ -2216,7 +2215,7 @@ public ch.epfl.dedis.lib.proto.TrieProto.InteriorNodeOrBuilder getInteriorsOrBui
      * required .trie.LeafNode leaf = 2;
      */
     public boolean hasLeaf() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000001) != 0);
     }
     /**
      * required .trie.LeafNode leaf = 2;
@@ -2237,7 +2236,7 @@ public ch.epfl.dedis.lib.proto.TrieProto.LeafNodeOrBuilder getLeafOrBuilder() {
      * required .trie.EmptyNode empty = 3;
      */
     public boolean hasEmpty() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return ((bitField0_ & 0x00000002) != 0);
     }
     /**
      * required .trie.EmptyNode empty = 3;
@@ -2258,7 +2257,7 @@ public ch.epfl.dedis.lib.proto.TrieProto.EmptyNodeOrBuilder getEmptyOrBuilder()
      * required bytes nonce = 4;
      */
     public boolean hasNonce() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return ((bitField0_ & 0x00000004) != 0);
     }
     /**
      * required bytes nonce = 4;
@@ -2306,13 +2305,13 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
       for (int i = 0; i < interiors_.size(); i++) {
         output.writeMessage(1, interiors_.get(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         output.writeMessage(2, getLeaf());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         output.writeMessage(3, getEmpty());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         output.writeBytes(4, nonce_);
       }
       unknownFields.writeTo(output);
@@ -2328,15 +2327,15 @@ public int getSerializedSize() {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, interiors_.get(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (((bitField0_ & 0x00000001) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getLeaf());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getEmpty());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (((bitField0_ & 0x00000004) != 0)) {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(4, nonce_);
       }
@@ -2355,26 +2354,25 @@ public boolean equals(final java.lang.Object obj) {
       }
       ch.epfl.dedis.lib.proto.TrieProto.Proof other = (ch.epfl.dedis.lib.proto.TrieProto.Proof) obj;
 
-      boolean result = true;
-      result = result && getInteriorsList()
-          .equals(other.getInteriorsList());
-      result = result && (hasLeaf() == other.hasLeaf());
+      if (!getInteriorsList()
+          .equals(other.getInteriorsList())) return false;
+      if (hasLeaf() != other.hasLeaf()) return false;
       if (hasLeaf()) {
-        result = result && getLeaf()
-            .equals(other.getLeaf());
+        if (!getLeaf()
+            .equals(other.getLeaf())) return false;
       }
-      result = result && (hasEmpty() == other.hasEmpty());
+      if (hasEmpty() != other.hasEmpty()) return false;
       if (hasEmpty()) {
-        result = result && getEmpty()
-            .equals(other.getEmpty());
+        if (!getEmpty()
+            .equals(other.getEmpty())) return false;
       }
-      result = result && (hasNonce() == other.hasNonce());
+      if (hasNonce() != other.hasNonce()) return false;
       if (hasNonce()) {
-        result = result && getNonce()
-            .equals(other.getNonce());
+        if (!getNonce()
+            .equals(other.getNonce())) return false;
       }
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
     @java.lang.Override
@@ -2589,7 +2587,7 @@ public ch.epfl.dedis.lib.proto.TrieProto.Proof buildPartial() {
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
         if (interiorsBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             interiors_ = java.util.Collections.unmodifiableList(interiors_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
@@ -2597,23 +2595,23 @@ public ch.epfl.dedis.lib.proto.TrieProto.Proof buildPartial() {
         } else {
           result.interiors_ = interiorsBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+        if (((from_bitField0_ & 0x00000002) != 0)) {
+          if (leafBuilder_ == null) {
+            result.leaf_ = leaf_;
+          } else {
+            result.leaf_ = leafBuilder_.build();
+          }
           to_bitField0_ |= 0x00000001;
         }
-        if (leafBuilder_ == null) {
-          result.leaf_ = leaf_;
-        } else {
-          result.leaf_ = leafBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+        if (((from_bitField0_ & 0x00000004) != 0)) {
+          if (emptyBuilder_ == null) {
+            result.empty_ = empty_;
+          } else {
+            result.empty_ = emptyBuilder_.build();
+          }
           to_bitField0_ |= 0x00000002;
         }
-        if (emptyBuilder_ == null) {
-          result.empty_ = empty_;
-        } else {
-          result.empty_ = emptyBuilder_.build();
-        }
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+        if (((from_bitField0_ & 0x00000008) != 0)) {
           to_bitField0_ |= 0x00000004;
         }
         result.nonce_ = nonce_;
@@ -2624,35 +2622,35 @@ public ch.epfl.dedis.lib.proto.TrieProto.Proof buildPartial() {
 
       @java.lang.Override
       public Builder clone() {
-        return (Builder) super.clone();
+        return super.clone();
       }
       @java.lang.Override
       public Builder setField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.setField(field, value);
+        return super.setField(field, value);
       }
       @java.lang.Override
       public Builder clearField(
           com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
+        return super.clearField(field);
       }
       @java.lang.Override
       public Builder clearOneof(
           com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
+        return super.clearOneof(oneof);
       }
       @java.lang.Override
       public Builder setRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
+        return super.setRepeatedField(field, index, value);
       }
       @java.lang.Override
       public Builder addRepeatedField(
           com.google.protobuf.Descriptors.FieldDescriptor field,
           java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
+        return super.addRepeatedField(field, value);
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
@@ -2751,7 +2749,7 @@ public Builder mergeFrom(
       private java.util.List interiors_ =
         java.util.Collections.emptyList();
       private void ensureInteriorsIsMutable() {
-        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        if (!((bitField0_ & 0x00000001) != 0)) {
           interiors_ = new java.util.ArrayList(interiors_);
           bitField0_ |= 0x00000001;
          }
@@ -2980,7 +2978,7 @@ public ch.epfl.dedis.lib.proto.TrieProto.InteriorNode.Builder addInteriorsBuilde
           interiorsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               ch.epfl.dedis.lib.proto.TrieProto.InteriorNode, ch.epfl.dedis.lib.proto.TrieProto.InteriorNode.Builder, ch.epfl.dedis.lib.proto.TrieProto.InteriorNodeOrBuilder>(
                   interiors_,
-                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
           interiors_ = null;
@@ -2988,14 +2986,14 @@ public ch.epfl.dedis.lib.proto.TrieProto.InteriorNode.Builder addInteriorsBuilde
         return interiorsBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.TrieProto.LeafNode leaf_ = null;
+      private ch.epfl.dedis.lib.proto.TrieProto.LeafNode leaf_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.TrieProto.LeafNode, ch.epfl.dedis.lib.proto.TrieProto.LeafNode.Builder, ch.epfl.dedis.lib.proto.TrieProto.LeafNodeOrBuilder> leafBuilder_;
       /**
        * required .trie.LeafNode leaf = 2;
        */
       public boolean hasLeaf() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return ((bitField0_ & 0x00000002) != 0);
       }
       /**
        * required .trie.LeafNode leaf = 2;
@@ -3042,7 +3040,7 @@ public Builder setLeaf(
        */
       public Builder mergeLeaf(ch.epfl.dedis.lib.proto.TrieProto.LeafNode value) {
         if (leafBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+          if (((bitField0_ & 0x00000002) != 0) &&
               leaf_ != null &&
               leaf_ != ch.epfl.dedis.lib.proto.TrieProto.LeafNode.getDefaultInstance()) {
             leaf_ =
@@ -3106,14 +3104,14 @@ public ch.epfl.dedis.lib.proto.TrieProto.LeafNodeOrBuilder getLeafOrBuilder() {
         return leafBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.TrieProto.EmptyNode empty_ = null;
+      private ch.epfl.dedis.lib.proto.TrieProto.EmptyNode empty_;
       private com.google.protobuf.SingleFieldBuilderV3<
           ch.epfl.dedis.lib.proto.TrieProto.EmptyNode, ch.epfl.dedis.lib.proto.TrieProto.EmptyNode.Builder, ch.epfl.dedis.lib.proto.TrieProto.EmptyNodeOrBuilder> emptyBuilder_;
       /**
        * required .trie.EmptyNode empty = 3;
        */
       public boolean hasEmpty() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return ((bitField0_ & 0x00000004) != 0);
       }
       /**
        * required .trie.EmptyNode empty = 3;
@@ -3160,7 +3158,7 @@ public Builder setEmpty(
        */
       public Builder mergeEmpty(ch.epfl.dedis.lib.proto.TrieProto.EmptyNode value) {
         if (emptyBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
+          if (((bitField0_ & 0x00000004) != 0) &&
               empty_ != null &&
               empty_ != ch.epfl.dedis.lib.proto.TrieProto.EmptyNode.getDefaultInstance()) {
             empty_ =
@@ -3229,7 +3227,7 @@ public ch.epfl.dedis.lib.proto.TrieProto.EmptyNodeOrBuilder getEmptyOrBuilder()
        * required bytes nonce = 4;
        */
       public boolean hasNonce() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return ((bitField0_ & 0x00000008) != 0);
       }
       /**
        * required bytes nonce = 4;
diff --git a/external/proto/calypso.proto b/external/proto/calypso.proto
index bfe987dcbb..144f5ac6f8 100644
--- a/external/proto/calypso.proto
+++ b/external/proto/calypso.proto
@@ -116,3 +116,64 @@ message GetLTSReply {
 message LtsInstanceInfo {
   required onet.Roster roster = 1;
 }
+
+//
+// V4 proposed extensions
+//
+
+// Auth holds all possible authentication structures. When using it to call
+// Authorise, only one of the fields must be non-nil.
+message Auth {
+  optional AuthByzCoin byzcoin = 1;
+  optional AuthX509Cert authx509cert = 2;
+}
+
+// AuthByzCoin holds the information necessary to authenticate a byzcoin request.
+// In the ByzCoin model, all requests are valid as long as they are stored in the
+// blockchain with the given ID.
+// The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+message AuthByzCoin {
+  required bytes byzcoinid = 1;
+  required uint64 ttl = 2;
+}
+
+// AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
+// request. In its simplest form, it is simply the CA that will have to sign the
+// certificates of the requesters.
+// The Threshold indicates how many clients must have signed the request before it
+// is accepted.
+message AuthX509Cert {
+  // Slice of ASN.1 encoded X509 certificates.
+  repeated bytes ca = 1;
+  required sint32 threshold = 2;
+}
+
+// Grant holds one of the possible grant proofs for a reencryption request. Each
+// grant proof must hold the secret to be reencrypted, the ephemeral key, as well
+// as the proof itself that the request is valid. For each of the authentication
+// schemes, this proof will be different.
+message Grant {
+  optional GrantByzCoin byzcoin = 1;
+  optional GrantX509Cert x509cert = 2;
+}
+
+// GrantByzCoin holds the proof of the write instance, holding the secret itself.
+// The proof of the read instance holds the ephemeral key. Both proofs can be
+// verified using one of the stored ByzCoinIDs.
+message GrantByzCoin {
+  // Write is the proof containing the write request.
+  required byzcoin.Proof write = 1;
+  // Read is the proof that he has been accepted to read the secret.
+  required byzcoin.Proof read = 2;
+}
+
+// GrantX509Cert holds the proof that at least a threshold number of clients
+// accepted the reencryption.
+// For each client, there must exist a certificate that can be verified by the
+// CA certificate from AuthX509Cert. Additionally, each client must sign the
+// following message:
+//   sha256( Secret | Ephemeral | Time )
+message GrantX509Cert {
+  required bytes secret = 1;
+  repeated bytes certificates = 2;
+}
diff --git a/proto.sh b/proto.sh
index 6116421198..8bd8d7df1c 100755
--- a/proto.sh
+++ b/proto.sh
@@ -6,8 +6,8 @@ set -u
 struct_files=(`find . -name proto.go | sort`)
 
 pv=`protoc --version`
-if [ "$pv" != "libprotoc 3.6.1" ]; then
-	echo "Protoc version $pv is not supported."
+if [ "$pv" != "libprotoc 3.6.1" and "$pv" != "libprotoc 3.7.1"]; then
+	echo "Protoc version $pv is not supported. Please install 3.6.1 or 3.7.1"
 	exit 1
 fi
 

From 95538a6ecfad1514cb8088a4b95555b21371d480 Mon Sep 17 00:00:00 2001
From: Linus Gasser 
Date: Tue, 9 Apr 2019 11:15:59 +0200
Subject: [PATCH 02/21] Initial files

---
 .../java/ch/epfl/dedis/lib/proto/Calypso.java | 4796 +----------
 .../java/ch/epfl/dedis/lib/proto/OCS.java     | 7342 +++++++++++++++++
 external/proto/calypso.proto                  |   61 -
 external/proto/ocs.proto                      |  103 +
 ocs/OCS.md                                    |   34 +
 ocs/README.md                                 |  115 +
 ocs/Reencrypt.md                              |   32 +
 ocs/api.go                                    |   64 +
 ocs/db.go                                     |   93 +
 calypso/api_v4.go => ocs/proto.go             |   93 +-
 ocs/protocol.go                               |  214 +
 ocs/protocol_struct.go                        |   53 +
 ocs/protocol_test.go                          |  460 ++
 ocs/service.go                                |  619 ++
 {calypso => ocs}/verify.go                    |    2 +-
 {calypso => ocs}/verify_test.go               |    2 +-
 16 files changed, 9174 insertions(+), 4909 deletions(-)
 create mode 100644 external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java
 create mode 100644 external/proto/ocs.proto
 create mode 100644 ocs/OCS.md
 create mode 100644 ocs/README.md
 create mode 100644 ocs/Reencrypt.md
 create mode 100644 ocs/api.go
 create mode 100644 ocs/db.go
 rename calypso/api_v4.go => ocs/proto.go (51%)
 create mode 100644 ocs/protocol.go
 create mode 100644 ocs/protocol_struct.go
 create mode 100644 ocs/protocol_test.go
 create mode 100644 ocs/service.go
 rename {calypso => ocs}/verify.go (98%)
 rename {calypso => ocs}/verify_test.go (99%)

diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java
index 4cd489c030..4bf21b15f3 100644
--- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java
+++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java
@@ -8512,4721 +8512,6 @@ public ch.epfl.dedis.lib.proto.Calypso.LtsInstanceInfo getDefaultInstanceForType
 
   }
 
-  public interface AuthOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:calypso.Auth)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * optional .calypso.AuthByzCoin byzcoin = 1;
-     */
-    boolean hasByzcoin();
-    /**
-     * optional .calypso.AuthByzCoin byzcoin = 1;
-     */
-    ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getByzcoin();
-    /**
-     * optional .calypso.AuthByzCoin byzcoin = 1;
-     */
-    ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder getByzcoinOrBuilder();
-
-    /**
-     * optional .calypso.AuthX509Cert authx509cert = 2;
-     */
-    boolean hasAuthx509Cert();
-    /**
-     * optional .calypso.AuthX509Cert authx509cert = 2;
-     */
-    ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getAuthx509Cert();
-    /**
-     * optional .calypso.AuthX509Cert authx509cert = 2;
-     */
-    ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder getAuthx509CertOrBuilder();
-  }
-  /**
-   * 
-   * Auth holds all possible authentication structures. When using it to call
-   * Authorise, only one of the fields must be non-nil.
-   * 
- * - * Protobuf type {@code calypso.Auth} - */ - public static final class Auth extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:calypso.Auth) - AuthOrBuilder { - private static final long serialVersionUID = 0L; - // Use Auth.newBuilder() to construct. - private Auth(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private Auth() { - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private Auth( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder subBuilder = null; - if (((bitField0_ & 0x00000001) != 0)) { - subBuilder = byzcoin_.toBuilder(); - } - byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(byzcoin_); - byzcoin_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000001; - break; - } - case 18: { - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder subBuilder = null; - if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = authx509Cert_.toBuilder(); - } - authx509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(authx509Cert_); - authx509Cert_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000002; - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Auth_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Auth_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.Auth.class, ch.epfl.dedis.lib.proto.Calypso.Auth.Builder.class); - } - - private int bitField0_; - public static final int BYZCOIN_FIELD_NUMBER = 1; - private ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin byzcoin_; - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - public boolean hasByzcoin() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getByzcoin() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance() : byzcoin_; - } - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder getByzcoinOrBuilder() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance() : byzcoin_; - } - - public static final int AUTHX509CERT_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert authx509Cert_; - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - public boolean hasAuthx509Cert() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getAuthx509Cert() { - return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance() : authx509Cert_; - } - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - public ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder getAuthx509CertOrBuilder() { - return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance() : authx509Cert_; - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } - } - if (hasAuthx509Cert()) { - if (!getAuthx509Cert().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } - } - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (((bitField0_ & 0x00000001) != 0)) { - output.writeMessage(1, getByzcoin()); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getAuthx509Cert()); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, getByzcoin()); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getAuthx509Cert()); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.Auth)) { - return super.equals(obj); - } - ch.epfl.dedis.lib.proto.Calypso.Auth other = (ch.epfl.dedis.lib.proto.Calypso.Auth) obj; - - if (hasByzcoin() != other.hasByzcoin()) return false; - if (hasByzcoin()) { - if (!getByzcoin() - .equals(other.getByzcoin())) return false; - } - if (hasAuthx509Cert() != other.hasAuthx509Cert()) return false; - if (hasAuthx509Cert()) { - if (!getAuthx509Cert() - .equals(other.getAuthx509Cert())) return false; - } - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - if (hasByzcoin()) { - hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; - hash = (53 * hash) + getByzcoin().hashCode(); - } - if (hasAuthx509Cert()) { - hash = (37 * hash) + AUTHX509CERT_FIELD_NUMBER; - hash = (53 * hash) + getAuthx509Cert().hashCode(); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.Auth parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.Auth prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - *
-     * Auth holds all possible authentication structures. When using it to call
-     * Authorise, only one of the fields must be non-nil.
-     * 
- * - * Protobuf type {@code calypso.Auth} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:calypso.Auth) - ch.epfl.dedis.lib.proto.Calypso.AuthOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Auth_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Auth_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.Auth.class, ch.epfl.dedis.lib.proto.Calypso.Auth.Builder.class); - } - - // Construct using ch.epfl.dedis.lib.proto.Calypso.Auth.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - getByzcoinFieldBuilder(); - getAuthx509CertFieldBuilder(); - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - if (byzcoinBuilder_ == null) { - byzcoin_ = null; - } else { - byzcoinBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000001); - if (authx509CertBuilder_ == null) { - authx509Cert_ = null; - } else { - authx509CertBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Auth_descriptor; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.Auth getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.Calypso.Auth.getDefaultInstance(); - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.Auth build() { - ch.epfl.dedis.lib.proto.Calypso.Auth result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.Auth buildPartial() { - ch.epfl.dedis.lib.proto.Calypso.Auth result = new ch.epfl.dedis.lib.proto.Calypso.Auth(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) != 0)) { - if (byzcoinBuilder_ == null) { - result.byzcoin_ = byzcoin_; - } else { - result.byzcoin_ = byzcoinBuilder_.build(); - } - to_bitField0_ |= 0x00000001; - } - if (((from_bitField0_ & 0x00000002) != 0)) { - if (authx509CertBuilder_ == null) { - result.authx509Cert_ = authx509Cert_; - } else { - result.authx509Cert_ = authx509CertBuilder_.build(); - } - to_bitField0_ |= 0x00000002; - } - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.Calypso.Auth) { - return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.Auth)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.Auth other) { - if (other == ch.epfl.dedis.lib.proto.Calypso.Auth.getDefaultInstance()) return this; - if (other.hasByzcoin()) { - mergeByzcoin(other.getByzcoin()); - } - if (other.hasAuthx509Cert()) { - mergeAuthx509Cert(other.getAuthx509Cert()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - return false; - } - } - if (hasAuthx509Cert()) { - if (!getAuthx509Cert().isInitialized()) { - return false; - } - } - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ch.epfl.dedis.lib.proto.Calypso.Auth parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.Auth) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - private ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin byzcoin_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder> byzcoinBuilder_; - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - public boolean hasByzcoin() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getByzcoin() { - if (byzcoinBuilder_ == null) { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance() : byzcoin_; - } else { - return byzcoinBuilder_.getMessage(); - } - } - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - public Builder setByzcoin(ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin value) { - if (byzcoinBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - byzcoin_ = value; - onChanged(); - } else { - byzcoinBuilder_.setMessage(value); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - public Builder setByzcoin( - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder builderForValue) { - if (byzcoinBuilder_ == null) { - byzcoin_ = builderForValue.build(); - onChanged(); - } else { - byzcoinBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin value) { - if (byzcoinBuilder_ == null) { - if (((bitField0_ & 0x00000001) != 0) && - byzcoin_ != null && - byzcoin_ != ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance()) { - byzcoin_ = - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); - } else { - byzcoin_ = value; - } - onChanged(); - } else { - byzcoinBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - public Builder clearByzcoin() { - if (byzcoinBuilder_ == null) { - byzcoin_ = null; - onChanged(); - } else { - byzcoinBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000001); - return this; - } - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder getByzcoinBuilder() { - bitField0_ |= 0x00000001; - onChanged(); - return getByzcoinFieldBuilder().getBuilder(); - } - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder getByzcoinOrBuilder() { - if (byzcoinBuilder_ != null) { - return byzcoinBuilder_.getMessageOrBuilder(); - } else { - return byzcoin_ == null ? - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance() : byzcoin_; - } - } - /** - * optional .calypso.AuthByzCoin byzcoin = 1; - */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder> - getByzcoinFieldBuilder() { - if (byzcoinBuilder_ == null) { - byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder>( - getByzcoin(), - getParentForChildren(), - isClean()); - byzcoin_ = null; - } - return byzcoinBuilder_; - } - - private ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert authx509Cert_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert, ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder> authx509CertBuilder_; - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - public boolean hasAuthx509Cert() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getAuthx509Cert() { - if (authx509CertBuilder_ == null) { - return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance() : authx509Cert_; - } else { - return authx509CertBuilder_.getMessage(); - } - } - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - public Builder setAuthx509Cert(ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert value) { - if (authx509CertBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - authx509Cert_ = value; - onChanged(); - } else { - authx509CertBuilder_.setMessage(value); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - public Builder setAuthx509Cert( - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder builderForValue) { - if (authx509CertBuilder_ == null) { - authx509Cert_ = builderForValue.build(); - onChanged(); - } else { - authx509CertBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - public Builder mergeAuthx509Cert(ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert value) { - if (authx509CertBuilder_ == null) { - if (((bitField0_ & 0x00000002) != 0) && - authx509Cert_ != null && - authx509Cert_ != ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance()) { - authx509Cert_ = - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.newBuilder(authx509Cert_).mergeFrom(value).buildPartial(); - } else { - authx509Cert_ = value; - } - onChanged(); - } else { - authx509CertBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - public Builder clearAuthx509Cert() { - if (authx509CertBuilder_ == null) { - authx509Cert_ = null; - onChanged(); - } else { - authx509CertBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder getAuthx509CertBuilder() { - bitField0_ |= 0x00000002; - onChanged(); - return getAuthx509CertFieldBuilder().getBuilder(); - } - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - public ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder getAuthx509CertOrBuilder() { - if (authx509CertBuilder_ != null) { - return authx509CertBuilder_.getMessageOrBuilder(); - } else { - return authx509Cert_ == null ? - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance() : authx509Cert_; - } - } - /** - * optional .calypso.AuthX509Cert authx509cert = 2; - */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert, ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder> - getAuthx509CertFieldBuilder() { - if (authx509CertBuilder_ == null) { - authx509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert, ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder>( - getAuthx509Cert(), - getParentForChildren(), - isClean()); - authx509Cert_ = null; - } - return authx509CertBuilder_; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:calypso.Auth) - } - - // @@protoc_insertion_point(class_scope:calypso.Auth) - private static final ch.epfl.dedis.lib.proto.Calypso.Auth DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.Auth(); - } - - public static ch.epfl.dedis.lib.proto.Calypso.Auth getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public Auth parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new Auth(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.Auth getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - - } - - public interface AuthByzCoinOrBuilder extends - // @@protoc_insertion_point(interface_extends:calypso.AuthByzCoin) - com.google.protobuf.MessageOrBuilder { - - /** - * required bytes byzcoinid = 1; - */ - boolean hasByzcoinid(); - /** - * required bytes byzcoinid = 1; - */ - com.google.protobuf.ByteString getByzcoinid(); - - /** - * required uint64 ttl = 2; - */ - boolean hasTtl(); - /** - * required uint64 ttl = 2; - */ - long getTtl(); - } - /** - *
-   * AuthByzCoin holds the information necessary to authenticate a byzcoin request.
-   * In the ByzCoin model, all requests are valid as long as they are stored in the
-   * blockchain with the given ID.
-   * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
-   * 
- * - * Protobuf type {@code calypso.AuthByzCoin} - */ - public static final class AuthByzCoin extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:calypso.AuthByzCoin) - AuthByzCoinOrBuilder { - private static final long serialVersionUID = 0L; - // Use AuthByzCoin.newBuilder() to construct. - private AuthByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private AuthByzCoin() { - byzcoinid_ = com.google.protobuf.ByteString.EMPTY; - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private AuthByzCoin( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - bitField0_ |= 0x00000001; - byzcoinid_ = input.readBytes(); - break; - } - case 16: { - bitField0_ |= 0x00000002; - ttl_ = input.readUInt64(); - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthByzCoin_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthByzCoin_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.class, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder.class); - } - - private int bitField0_; - public static final int BYZCOINID_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString byzcoinid_; - /** - * required bytes byzcoinid = 1; - */ - public boolean hasByzcoinid() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * required bytes byzcoinid = 1; - */ - public com.google.protobuf.ByteString getByzcoinid() { - return byzcoinid_; - } - - public static final int TTL_FIELD_NUMBER = 2; - private long ttl_; - /** - * required uint64 ttl = 2; - */ - public boolean hasTtl() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * required uint64 ttl = 2; - */ - public long getTtl() { - return ttl_; - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - if (!hasByzcoinid()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasTtl()) { - memoizedIsInitialized = 0; - return false; - } - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, byzcoinid_); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeUInt64(2, ttl_); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, byzcoinid_); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt64Size(2, ttl_); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin)) { - return super.equals(obj); - } - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin other = (ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin) obj; - - if (hasByzcoinid() != other.hasByzcoinid()) return false; - if (hasByzcoinid()) { - if (!getByzcoinid() - .equals(other.getByzcoinid())) return false; - } - if (hasTtl() != other.hasTtl()) return false; - if (hasTtl()) { - if (getTtl() - != other.getTtl()) return false; - } - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - if (hasByzcoinid()) { - hash = (37 * hash) + BYZCOINID_FIELD_NUMBER; - hash = (53 * hash) + getByzcoinid().hashCode(); - } - if (hasTtl()) { - hash = (37 * hash) + TTL_FIELD_NUMBER; - hash = (53 * hash) + com.google.protobuf.Internal.hashLong( - getTtl()); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - *
-     * AuthByzCoin holds the information necessary to authenticate a byzcoin request.
-     * In the ByzCoin model, all requests are valid as long as they are stored in the
-     * blockchain with the given ID.
-     * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
-     * 
- * - * Protobuf type {@code calypso.AuthByzCoin} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:calypso.AuthByzCoin) - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoinOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthByzCoin_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthByzCoin_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.class, ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.Builder.class); - } - - // Construct using ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - byzcoinid_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000001); - ttl_ = 0L; - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthByzCoin_descriptor; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance(); - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin build() { - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin buildPartial() { - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin result = new ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) != 0)) { - to_bitField0_ |= 0x00000001; - } - result.byzcoinid_ = byzcoinid_; - if (((from_bitField0_ & 0x00000002) != 0)) { - result.ttl_ = ttl_; - to_bitField0_ |= 0x00000002; - } - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin) { - return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin other) { - if (other == ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin.getDefaultInstance()) return this; - if (other.hasByzcoinid()) { - setByzcoinid(other.getByzcoinid()); - } - if (other.hasTtl()) { - setTtl(other.getTtl()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - if (!hasByzcoinid()) { - return false; - } - if (!hasTtl()) { - return false; - } - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - private com.google.protobuf.ByteString byzcoinid_ = com.google.protobuf.ByteString.EMPTY; - /** - * required bytes byzcoinid = 1; - */ - public boolean hasByzcoinid() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * required bytes byzcoinid = 1; - */ - public com.google.protobuf.ByteString getByzcoinid() { - return byzcoinid_; - } - /** - * required bytes byzcoinid = 1; - */ - public Builder setByzcoinid(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - byzcoinid_ = value; - onChanged(); - return this; - } - /** - * required bytes byzcoinid = 1; - */ - public Builder clearByzcoinid() { - bitField0_ = (bitField0_ & ~0x00000001); - byzcoinid_ = getDefaultInstance().getByzcoinid(); - onChanged(); - return this; - } - - private long ttl_ ; - /** - * required uint64 ttl = 2; - */ - public boolean hasTtl() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * required uint64 ttl = 2; - */ - public long getTtl() { - return ttl_; - } - /** - * required uint64 ttl = 2; - */ - public Builder setTtl(long value) { - bitField0_ |= 0x00000002; - ttl_ = value; - onChanged(); - return this; - } - /** - * required uint64 ttl = 2; - */ - public Builder clearTtl() { - bitField0_ = (bitField0_ & ~0x00000002); - ttl_ = 0L; - onChanged(); - return this; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:calypso.AuthByzCoin) - } - - // @@protoc_insertion_point(class_scope:calypso.AuthByzCoin) - private static final ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin(); - } - - public static ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public AuthByzCoin parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new AuthByzCoin(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.AuthByzCoin getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - - } - - public interface AuthX509CertOrBuilder extends - // @@protoc_insertion_point(interface_extends:calypso.AuthX509Cert) - com.google.protobuf.MessageOrBuilder { - - /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; - */ - java.util.List getCaList(); - /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; - */ - int getCaCount(); - /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; - */ - com.google.protobuf.ByteString getCa(int index); - - /** - * required sint32 threshold = 2; - */ - boolean hasThreshold(); - /** - * required sint32 threshold = 2; - */ - int getThreshold(); - } - /** - *
-   * AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
-   * request. In its simplest form, it is simply the CA that will have to sign the
-   * certificates of the requesters.
-   * The Threshold indicates how many clients must have signed the request before it
-   * is accepted.
-   * 
- * - * Protobuf type {@code calypso.AuthX509Cert} - */ - public static final class AuthX509Cert extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:calypso.AuthX509Cert) - AuthX509CertOrBuilder { - private static final long serialVersionUID = 0L; - // Use AuthX509Cert.newBuilder() to construct. - private AuthX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private AuthX509Cert() { - ca_ = java.util.Collections.emptyList(); - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private AuthX509Cert( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - if (!((mutable_bitField0_ & 0x00000001) != 0)) { - ca_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000001; - } - ca_.add(input.readBytes()); - break; - } - case 16: { - bitField0_ |= 0x00000001; - threshold_ = input.readSInt32(); - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - if (((mutable_bitField0_ & 0x00000001) != 0)) { - ca_ = java.util.Collections.unmodifiableList(ca_); // C - } - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthX509Cert_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthX509Cert_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.class, ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder.class); - } - - private int bitField0_; - public static final int CA_FIELD_NUMBER = 1; - private java.util.List ca_; - /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; - */ - public java.util.List - getCaList() { - return ca_; - } - /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; - */ - public int getCaCount() { - return ca_.size(); - } - /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; - */ - public com.google.protobuf.ByteString getCa(int index) { - return ca_.get(index); - } - - public static final int THRESHOLD_FIELD_NUMBER = 2; - private int threshold_; - /** - * required sint32 threshold = 2; - */ - public boolean hasThreshold() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * required sint32 threshold = 2; - */ - public int getThreshold() { - return threshold_; - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - if (!hasThreshold()) { - memoizedIsInitialized = 0; - return false; - } - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - for (int i = 0; i < ca_.size(); i++) { - output.writeBytes(1, ca_.get(i)); - } - if (((bitField0_ & 0x00000001) != 0)) { - output.writeSInt32(2, threshold_); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - { - int dataSize = 0; - for (int i = 0; i < ca_.size(); i++) { - dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(ca_.get(i)); - } - size += dataSize; - size += 1 * getCaList().size(); - } - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeSInt32Size(2, threshold_); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert)) { - return super.equals(obj); - } - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert other = (ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert) obj; - - if (!getCaList() - .equals(other.getCaList())) return false; - if (hasThreshold() != other.hasThreshold()) return false; - if (hasThreshold()) { - if (getThreshold() - != other.getThreshold()) return false; - } - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - if (getCaCount() > 0) { - hash = (37 * hash) + CA_FIELD_NUMBER; - hash = (53 * hash) + getCaList().hashCode(); - } - if (hasThreshold()) { - hash = (37 * hash) + THRESHOLD_FIELD_NUMBER; - hash = (53 * hash) + getThreshold(); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - *
-     * AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
-     * request. In its simplest form, it is simply the CA that will have to sign the
-     * certificates of the requesters.
-     * The Threshold indicates how many clients must have signed the request before it
-     * is accepted.
-     * 
- * - * Protobuf type {@code calypso.AuthX509Cert} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:calypso.AuthX509Cert) - ch.epfl.dedis.lib.proto.Calypso.AuthX509CertOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthX509Cert_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthX509Cert_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.class, ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.Builder.class); - } - - // Construct using ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - ca_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000001); - threshold_ = 0; - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_AuthX509Cert_descriptor; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance(); - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert build() { - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert buildPartial() { - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert result = new ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((bitField0_ & 0x00000001) != 0)) { - ca_ = java.util.Collections.unmodifiableList(ca_); - bitField0_ = (bitField0_ & ~0x00000001); - } - result.ca_ = ca_; - if (((from_bitField0_ & 0x00000002) != 0)) { - result.threshold_ = threshold_; - to_bitField0_ |= 0x00000001; - } - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert) { - return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert other) { - if (other == ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert.getDefaultInstance()) return this; - if (!other.ca_.isEmpty()) { - if (ca_.isEmpty()) { - ca_ = other.ca_; - bitField0_ = (bitField0_ & ~0x00000001); - } else { - ensureCaIsMutable(); - ca_.addAll(other.ca_); - } - onChanged(); - } - if (other.hasThreshold()) { - setThreshold(other.getThreshold()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - if (!hasThreshold()) { - return false; - } - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - private java.util.List ca_ = java.util.Collections.emptyList(); - private void ensureCaIsMutable() { - if (!((bitField0_ & 0x00000001) != 0)) { - ca_ = new java.util.ArrayList(ca_); - bitField0_ |= 0x00000001; - } - } - /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; - */ - public java.util.List - getCaList() { - return ((bitField0_ & 0x00000001) != 0) ? - java.util.Collections.unmodifiableList(ca_) : ca_; - } - /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; - */ - public int getCaCount() { - return ca_.size(); - } - /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; - */ - public com.google.protobuf.ByteString getCa(int index) { - return ca_.get(index); - } - /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; - */ - public Builder setCa( - int index, com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureCaIsMutable(); - ca_.set(index, value); - onChanged(); - return this; - } - /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; - */ - public Builder addCa(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureCaIsMutable(); - ca_.add(value); - onChanged(); - return this; - } - /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; - */ - public Builder addAllCa( - java.lang.Iterable values) { - ensureCaIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, ca_); - onChanged(); - return this; - } - /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; - */ - public Builder clearCa() { - ca_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000001); - onChanged(); - return this; - } - - private int threshold_ ; - /** - * required sint32 threshold = 2; - */ - public boolean hasThreshold() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * required sint32 threshold = 2; - */ - public int getThreshold() { - return threshold_; - } - /** - * required sint32 threshold = 2; - */ - public Builder setThreshold(int value) { - bitField0_ |= 0x00000002; - threshold_ = value; - onChanged(); - return this; - } - /** - * required sint32 threshold = 2; - */ - public Builder clearThreshold() { - bitField0_ = (bitField0_ & ~0x00000002); - threshold_ = 0; - onChanged(); - return this; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:calypso.AuthX509Cert) - } - - // @@protoc_insertion_point(class_scope:calypso.AuthX509Cert) - private static final ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert(); - } - - public static ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public AuthX509Cert parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new AuthX509Cert(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.AuthX509Cert getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - - } - - public interface GrantOrBuilder extends - // @@protoc_insertion_point(interface_extends:calypso.Grant) - com.google.protobuf.MessageOrBuilder { - - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - boolean hasByzcoin(); - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getByzcoin(); - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder getByzcoinOrBuilder(); - - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - boolean hasX509Cert(); - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getX509Cert(); - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder getX509CertOrBuilder(); - } - /** - *
-   * Grant holds one of the possible grant proofs for a reencryption request. Each
-   * grant proof must hold the secret to be reencrypted, the ephemeral key, as well
-   * as the proof itself that the request is valid. For each of the authentication
-   * schemes, this proof will be different.
-   * 
- * - * Protobuf type {@code calypso.Grant} - */ - public static final class Grant extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:calypso.Grant) - GrantOrBuilder { - private static final long serialVersionUID = 0L; - // Use Grant.newBuilder() to construct. - private Grant(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private Grant() { - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private Grant( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder subBuilder = null; - if (((bitField0_ & 0x00000001) != 0)) { - subBuilder = byzcoin_.toBuilder(); - } - byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(byzcoin_); - byzcoin_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000001; - break; - } - case 18: { - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder subBuilder = null; - if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = x509Cert_.toBuilder(); - } - x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(x509Cert_); - x509Cert_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000002; - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Grant_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Grant_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.Grant.class, ch.epfl.dedis.lib.proto.Calypso.Grant.Builder.class); - } - - private int bitField0_; - public static final int BYZCOIN_FIELD_NUMBER = 1; - private ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin byzcoin_; - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - public boolean hasByzcoin() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getByzcoin() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance() : byzcoin_; - } - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder getByzcoinOrBuilder() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance() : byzcoin_; - } - - public static final int X509CERT_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert x509Cert_; - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - public boolean hasX509Cert() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getX509Cert() { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance() : x509Cert_; - } - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - public ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder getX509CertOrBuilder() { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance() : x509Cert_; - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } - } - if (hasX509Cert()) { - if (!getX509Cert().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } - } - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (((bitField0_ & 0x00000001) != 0)) { - output.writeMessage(1, getByzcoin()); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getX509Cert()); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, getByzcoin()); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getX509Cert()); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.Grant)) { - return super.equals(obj); - } - ch.epfl.dedis.lib.proto.Calypso.Grant other = (ch.epfl.dedis.lib.proto.Calypso.Grant) obj; - - if (hasByzcoin() != other.hasByzcoin()) return false; - if (hasByzcoin()) { - if (!getByzcoin() - .equals(other.getByzcoin())) return false; - } - if (hasX509Cert() != other.hasX509Cert()) return false; - if (hasX509Cert()) { - if (!getX509Cert() - .equals(other.getX509Cert())) return false; - } - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - if (hasByzcoin()) { - hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; - hash = (53 * hash) + getByzcoin().hashCode(); - } - if (hasX509Cert()) { - hash = (37 * hash) + X509CERT_FIELD_NUMBER; - hash = (53 * hash) + getX509Cert().hashCode(); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.Grant parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.Grant prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - *
-     * Grant holds one of the possible grant proofs for a reencryption request. Each
-     * grant proof must hold the secret to be reencrypted, the ephemeral key, as well
-     * as the proof itself that the request is valid. For each of the authentication
-     * schemes, this proof will be different.
-     * 
- * - * Protobuf type {@code calypso.Grant} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:calypso.Grant) - ch.epfl.dedis.lib.proto.Calypso.GrantOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Grant_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Grant_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.Grant.class, ch.epfl.dedis.lib.proto.Calypso.Grant.Builder.class); - } - - // Construct using ch.epfl.dedis.lib.proto.Calypso.Grant.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - getByzcoinFieldBuilder(); - getX509CertFieldBuilder(); - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - if (byzcoinBuilder_ == null) { - byzcoin_ = null; - } else { - byzcoinBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000001); - if (x509CertBuilder_ == null) { - x509Cert_ = null; - } else { - x509CertBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_Grant_descriptor; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.Grant getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.Calypso.Grant.getDefaultInstance(); - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.Grant build() { - ch.epfl.dedis.lib.proto.Calypso.Grant result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.Grant buildPartial() { - ch.epfl.dedis.lib.proto.Calypso.Grant result = new ch.epfl.dedis.lib.proto.Calypso.Grant(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) != 0)) { - if (byzcoinBuilder_ == null) { - result.byzcoin_ = byzcoin_; - } else { - result.byzcoin_ = byzcoinBuilder_.build(); - } - to_bitField0_ |= 0x00000001; - } - if (((from_bitField0_ & 0x00000002) != 0)) { - if (x509CertBuilder_ == null) { - result.x509Cert_ = x509Cert_; - } else { - result.x509Cert_ = x509CertBuilder_.build(); - } - to_bitField0_ |= 0x00000002; - } - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.Calypso.Grant) { - return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.Grant)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.Grant other) { - if (other == ch.epfl.dedis.lib.proto.Calypso.Grant.getDefaultInstance()) return this; - if (other.hasByzcoin()) { - mergeByzcoin(other.getByzcoin()); - } - if (other.hasX509Cert()) { - mergeX509Cert(other.getX509Cert()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - return false; - } - } - if (hasX509Cert()) { - if (!getX509Cert().isInitialized()) { - return false; - } - } - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ch.epfl.dedis.lib.proto.Calypso.Grant parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.Grant) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - private ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin byzcoin_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder> byzcoinBuilder_; - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - public boolean hasByzcoin() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getByzcoin() { - if (byzcoinBuilder_ == null) { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance() : byzcoin_; - } else { - return byzcoinBuilder_.getMessage(); - } - } - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - public Builder setByzcoin(ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin value) { - if (byzcoinBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - byzcoin_ = value; - onChanged(); - } else { - byzcoinBuilder_.setMessage(value); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - public Builder setByzcoin( - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder builderForValue) { - if (byzcoinBuilder_ == null) { - byzcoin_ = builderForValue.build(); - onChanged(); - } else { - byzcoinBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin value) { - if (byzcoinBuilder_ == null) { - if (((bitField0_ & 0x00000001) != 0) && - byzcoin_ != null && - byzcoin_ != ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance()) { - byzcoin_ = - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); - } else { - byzcoin_ = value; - } - onChanged(); - } else { - byzcoinBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - public Builder clearByzcoin() { - if (byzcoinBuilder_ == null) { - byzcoin_ = null; - onChanged(); - } else { - byzcoinBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000001); - return this; - } - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder getByzcoinBuilder() { - bitField0_ |= 0x00000001; - onChanged(); - return getByzcoinFieldBuilder().getBuilder(); - } - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder getByzcoinOrBuilder() { - if (byzcoinBuilder_ != null) { - return byzcoinBuilder_.getMessageOrBuilder(); - } else { - return byzcoin_ == null ? - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance() : byzcoin_; - } - } - /** - * optional .calypso.GrantByzCoin byzcoin = 1; - */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder> - getByzcoinFieldBuilder() { - if (byzcoinBuilder_ == null) { - byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder>( - getByzcoin(), - getParentForChildren(), - isClean()); - byzcoin_ = null; - } - return byzcoinBuilder_; - } - - private ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert x509Cert_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert, ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder> x509CertBuilder_; - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - public boolean hasX509Cert() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getX509Cert() { - if (x509CertBuilder_ == null) { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance() : x509Cert_; - } else { - return x509CertBuilder_.getMessage(); - } - } - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - public Builder setX509Cert(ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert value) { - if (x509CertBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - x509Cert_ = value; - onChanged(); - } else { - x509CertBuilder_.setMessage(value); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - public Builder setX509Cert( - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder builderForValue) { - if (x509CertBuilder_ == null) { - x509Cert_ = builderForValue.build(); - onChanged(); - } else { - x509CertBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert value) { - if (x509CertBuilder_ == null) { - if (((bitField0_ & 0x00000002) != 0) && - x509Cert_ != null && - x509Cert_ != ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance()) { - x509Cert_ = - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); - } else { - x509Cert_ = value; - } - onChanged(); - } else { - x509CertBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - public Builder clearX509Cert() { - if (x509CertBuilder_ == null) { - x509Cert_ = null; - onChanged(); - } else { - x509CertBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder getX509CertBuilder() { - bitField0_ |= 0x00000002; - onChanged(); - return getX509CertFieldBuilder().getBuilder(); - } - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - public ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder getX509CertOrBuilder() { - if (x509CertBuilder_ != null) { - return x509CertBuilder_.getMessageOrBuilder(); - } else { - return x509Cert_ == null ? - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance() : x509Cert_; - } - } - /** - * optional .calypso.GrantX509Cert x509cert = 2; - */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert, ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder> - getX509CertFieldBuilder() { - if (x509CertBuilder_ == null) { - x509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert, ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder>( - getX509Cert(), - getParentForChildren(), - isClean()); - x509Cert_ = null; - } - return x509CertBuilder_; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:calypso.Grant) - } - - // @@protoc_insertion_point(class_scope:calypso.Grant) - private static final ch.epfl.dedis.lib.proto.Calypso.Grant DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.Grant(); - } - - public static ch.epfl.dedis.lib.proto.Calypso.Grant getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public Grant parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new Grant(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.Grant getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - - } - - public interface GrantByzCoinOrBuilder extends - // @@protoc_insertion_point(interface_extends:calypso.GrantByzCoin) - com.google.protobuf.MessageOrBuilder { - - /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required .byzcoin.Proof write = 1; - */ - boolean hasWrite(); - /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required .byzcoin.Proof write = 1; - */ - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getWrite(); - /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required .byzcoin.Proof write = 1; - */ - ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getWriteOrBuilder(); - - /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required .byzcoin.Proof read = 2; - */ - boolean hasRead(); - /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required .byzcoin.Proof read = 2; - */ - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getRead(); - /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required .byzcoin.Proof read = 2; - */ - ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getReadOrBuilder(); - } - /** - *
-   * GrantByzCoin holds the proof of the write instance, holding the secret itself.
-   * The proof of the read instance holds the ephemeral key. Both proofs can be
-   * verified using one of the stored ByzCoinIDs.
-   * 
- * - * Protobuf type {@code calypso.GrantByzCoin} - */ - public static final class GrantByzCoin extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:calypso.GrantByzCoin) - GrantByzCoinOrBuilder { - private static final long serialVersionUID = 0L; - // Use GrantByzCoin.newBuilder() to construct. - private GrantByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private GrantByzCoin() { - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private GrantByzCoin( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder subBuilder = null; - if (((bitField0_ & 0x00000001) != 0)) { - subBuilder = write_.toBuilder(); - } - write_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(write_); - write_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000001; - break; - } - case 18: { - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder subBuilder = null; - if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = read_.toBuilder(); - } - read_ = input.readMessage(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(read_); - read_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000002; - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantByzCoin_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantByzCoin_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.class, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder.class); - } - - private int bitField0_; - public static final int WRITE_FIELD_NUMBER = 1; - private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof write_; - /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required .byzcoin.Proof write = 1; - */ - public boolean hasWrite() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required .byzcoin.Proof write = 1; - */ - public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getWrite() { - return write_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : write_; - } - /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required .byzcoin.Proof write = 1; - */ - public ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getWriteOrBuilder() { - return write_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : write_; - } - - public static final int READ_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof read_; - /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required .byzcoin.Proof read = 2; - */ - public boolean hasRead() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required .byzcoin.Proof read = 2; - */ - public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getRead() { - return read_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : read_; - } - /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required .byzcoin.Proof read = 2; - */ - public ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getReadOrBuilder() { - return read_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : read_; - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - if (!hasWrite()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasRead()) { - memoizedIsInitialized = 0; - return false; - } - if (!getWrite().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } - if (!getRead().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (((bitField0_ & 0x00000001) != 0)) { - output.writeMessage(1, getWrite()); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getRead()); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, getWrite()); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getRead()); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin)) { - return super.equals(obj); - } - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin other = (ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin) obj; - - if (hasWrite() != other.hasWrite()) return false; - if (hasWrite()) { - if (!getWrite() - .equals(other.getWrite())) return false; - } - if (hasRead() != other.hasRead()) return false; - if (hasRead()) { - if (!getRead() - .equals(other.getRead())) return false; - } - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - if (hasWrite()) { - hash = (37 * hash) + WRITE_FIELD_NUMBER; - hash = (53 * hash) + getWrite().hashCode(); - } - if (hasRead()) { - hash = (37 * hash) + READ_FIELD_NUMBER; - hash = (53 * hash) + getRead().hashCode(); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - *
-     * GrantByzCoin holds the proof of the write instance, holding the secret itself.
-     * The proof of the read instance holds the ephemeral key. Both proofs can be
-     * verified using one of the stored ByzCoinIDs.
-     * 
- * - * Protobuf type {@code calypso.GrantByzCoin} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:calypso.GrantByzCoin) - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoinOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantByzCoin_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantByzCoin_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.class, ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.Builder.class); - } - - // Construct using ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - getWriteFieldBuilder(); - getReadFieldBuilder(); - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - if (writeBuilder_ == null) { - write_ = null; - } else { - writeBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000001); - if (readBuilder_ == null) { - read_ = null; - } else { - readBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantByzCoin_descriptor; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance(); - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin build() { - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin buildPartial() { - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin result = new ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) != 0)) { - if (writeBuilder_ == null) { - result.write_ = write_; - } else { - result.write_ = writeBuilder_.build(); - } - to_bitField0_ |= 0x00000001; - } - if (((from_bitField0_ & 0x00000002) != 0)) { - if (readBuilder_ == null) { - result.read_ = read_; - } else { - result.read_ = readBuilder_.build(); - } - to_bitField0_ |= 0x00000002; - } - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin) { - return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin other) { - if (other == ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin.getDefaultInstance()) return this; - if (other.hasWrite()) { - mergeWrite(other.getWrite()); - } - if (other.hasRead()) { - mergeRead(other.getRead()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - if (!hasWrite()) { - return false; - } - if (!hasRead()) { - return false; - } - if (!getWrite().isInitialized()) { - return false; - } - if (!getRead().isInitialized()) { - return false; - } - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof write_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> writeBuilder_; - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required .byzcoin.Proof write = 1; - */ - public boolean hasWrite() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required .byzcoin.Proof write = 1; - */ - public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getWrite() { - if (writeBuilder_ == null) { - return write_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : write_; - } else { - return writeBuilder_.getMessage(); - } - } - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required .byzcoin.Proof write = 1; - */ - public Builder setWrite(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) { - if (writeBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - write_ = value; - onChanged(); - } else { - writeBuilder_.setMessage(value); - } - bitField0_ |= 0x00000001; - return this; - } - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required .byzcoin.Proof write = 1; - */ - public Builder setWrite( - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder builderForValue) { - if (writeBuilder_ == null) { - write_ = builderForValue.build(); - onChanged(); - } else { - writeBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000001; - return this; - } - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required .byzcoin.Proof write = 1; - */ - public Builder mergeWrite(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) { - if (writeBuilder_ == null) { - if (((bitField0_ & 0x00000001) != 0) && - write_ != null && - write_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance()) { - write_ = - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.newBuilder(write_).mergeFrom(value).buildPartial(); - } else { - write_ = value; - } - onChanged(); - } else { - writeBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000001; - return this; - } - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required .byzcoin.Proof write = 1; - */ - public Builder clearWrite() { - if (writeBuilder_ == null) { - write_ = null; - onChanged(); - } else { - writeBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000001); - return this; - } - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required .byzcoin.Proof write = 1; - */ - public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder getWriteBuilder() { - bitField0_ |= 0x00000001; - onChanged(); - return getWriteFieldBuilder().getBuilder(); - } - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required .byzcoin.Proof write = 1; - */ - public ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getWriteOrBuilder() { - if (writeBuilder_ != null) { - return writeBuilder_.getMessageOrBuilder(); - } else { - return write_ == null ? - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : write_; - } - } - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required .byzcoin.Proof write = 1; - */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> - getWriteFieldBuilder() { - if (writeBuilder_ == null) { - writeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder>( - getWrite(), - getParentForChildren(), - isClean()); - write_ = null; - } - return writeBuilder_; - } - - private ch.epfl.dedis.lib.proto.ByzCoinProto.Proof read_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> readBuilder_; - /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required .byzcoin.Proof read = 2; - */ - public boolean hasRead() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required .byzcoin.Proof read = 2; - */ - public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof getRead() { - if (readBuilder_ == null) { - return read_ == null ? ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : read_; - } else { - return readBuilder_.getMessage(); - } - } - /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required .byzcoin.Proof read = 2; - */ - public Builder setRead(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) { - if (readBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - read_ = value; - onChanged(); - } else { - readBuilder_.setMessage(value); - } - bitField0_ |= 0x00000002; - return this; - } - /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required .byzcoin.Proof read = 2; - */ - public Builder setRead( - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder builderForValue) { - if (readBuilder_ == null) { - read_ = builderForValue.build(); - onChanged(); - } else { - readBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000002; - return this; - } - /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required .byzcoin.Proof read = 2; - */ - public Builder mergeRead(ch.epfl.dedis.lib.proto.ByzCoinProto.Proof value) { - if (readBuilder_ == null) { - if (((bitField0_ & 0x00000002) != 0) && - read_ != null && - read_ != ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance()) { - read_ = - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.newBuilder(read_).mergeFrom(value).buildPartial(); - } else { - read_ = value; - } - onChanged(); - } else { - readBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000002; - return this; - } - /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required .byzcoin.Proof read = 2; - */ - public Builder clearRead() { - if (readBuilder_ == null) { - read_ = null; - onChanged(); - } else { - readBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required .byzcoin.Proof read = 2; - */ - public ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder getReadBuilder() { - bitField0_ |= 0x00000002; - onChanged(); - return getReadFieldBuilder().getBuilder(); - } - /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required .byzcoin.Proof read = 2; - */ - public ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder getReadOrBuilder() { - if (readBuilder_ != null) { - return readBuilder_.getMessageOrBuilder(); - } else { - return read_ == null ? - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.getDefaultInstance() : read_; - } - } - /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required .byzcoin.Proof read = 2; - */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder> - getReadFieldBuilder() { - if (readBuilder_ == null) { - readBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.ByzCoinProto.Proof, ch.epfl.dedis.lib.proto.ByzCoinProto.Proof.Builder, ch.epfl.dedis.lib.proto.ByzCoinProto.ProofOrBuilder>( - getRead(), - getParentForChildren(), - isClean()); - read_ = null; - } - return readBuilder_; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:calypso.GrantByzCoin) - } - - // @@protoc_insertion_point(class_scope:calypso.GrantByzCoin) - private static final ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin(); - } - - public static ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public GrantByzCoin parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new GrantByzCoin(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.GrantByzCoin getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - - } - - public interface GrantX509CertOrBuilder extends - // @@protoc_insertion_point(interface_extends:calypso.GrantX509Cert) - com.google.protobuf.MessageOrBuilder { - - /** - * required bytes secret = 1; - */ - boolean hasSecret(); - /** - * required bytes secret = 1; - */ - com.google.protobuf.ByteString getSecret(); - - /** - * repeated bytes certificates = 2; - */ - java.util.List getCertificatesList(); - /** - * repeated bytes certificates = 2; - */ - int getCertificatesCount(); - /** - * repeated bytes certificates = 2; - */ - com.google.protobuf.ByteString getCertificates(int index); - } - /** - *
-   * GrantX509Cert holds the proof that at least a threshold number of clients
-   * accepted the reencryption.
-   * For each client, there must exist a certificate that can be verified by the
-   * CA certificate from AuthX509Cert. Additionally, each client must sign the
-   * following message:
-   *   sha256( Secret | Ephemeral | Time )
-   * 
- * - * Protobuf type {@code calypso.GrantX509Cert} - */ - public static final class GrantX509Cert extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:calypso.GrantX509Cert) - GrantX509CertOrBuilder { - private static final long serialVersionUID = 0L; - // Use GrantX509Cert.newBuilder() to construct. - private GrantX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private GrantX509Cert() { - secret_ = com.google.protobuf.ByteString.EMPTY; - certificates_ = java.util.Collections.emptyList(); - } - - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private GrantX509Cert( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); - } - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - bitField0_ |= 0x00000001; - secret_ = input.readBytes(); - break; - } - case 18: { - if (!((mutable_bitField0_ & 0x00000002) != 0)) { - certificates_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000002; - } - certificates_.add(input.readBytes()); - break; - } - default: { - if (!parseUnknownField( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - if (((mutable_bitField0_ & 0x00000002) != 0)) { - certificates_ = java.util.Collections.unmodifiableList(certificates_); // C - } - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantX509Cert_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantX509Cert_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.class, ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder.class); - } - - private int bitField0_; - public static final int SECRET_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString secret_; - /** - * required bytes secret = 1; - */ - public boolean hasSecret() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * required bytes secret = 1; - */ - public com.google.protobuf.ByteString getSecret() { - return secret_; - } - - public static final int CERTIFICATES_FIELD_NUMBER = 2; - private java.util.List certificates_; - /** - * repeated bytes certificates = 2; - */ - public java.util.List - getCertificatesList() { - return certificates_; - } - /** - * repeated bytes certificates = 2; - */ - public int getCertificatesCount() { - return certificates_.size(); - } - /** - * repeated bytes certificates = 2; - */ - public com.google.protobuf.ByteString getCertificates(int index) { - return certificates_.get(index); - } - - private byte memoizedIsInitialized = -1; - @java.lang.Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - if (!hasSecret()) { - memoizedIsInitialized = 0; - return false; - } - memoizedIsInitialized = 1; - return true; - } - - @java.lang.Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, secret_); - } - for (int i = 0; i < certificates_.size(); i++) { - output.writeBytes(2, certificates_.get(i)); - } - unknownFields.writeTo(output); - } - - @java.lang.Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, secret_); - } - { - int dataSize = 0; - for (int i = 0; i < certificates_.size(); i++) { - dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(certificates_.get(i)); - } - size += dataSize; - size += 1 * getCertificatesList().size(); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @java.lang.Override - public boolean equals(final java.lang.Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert)) { - return super.equals(obj); - } - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert other = (ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert) obj; - - if (hasSecret() != other.hasSecret()) return false; - if (hasSecret()) { - if (!getSecret() - .equals(other.getSecret())) return false; - } - if (!getCertificatesList() - .equals(other.getCertificatesList())) return false; - if (!unknownFields.equals(other.unknownFields)) return false; - return true; - } - - @java.lang.Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - if (hasSecret()) { - hash = (37 * hash) + SECRET_FIELD_NUMBER; - hash = (53 * hash) + getSecret().hashCode(); - } - if (getCertificatesCount() > 0) { - hash = (37 * hash) + CERTIFICATES_FIELD_NUMBER; - hash = (53 * hash) + getCertificatesList().hashCode(); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @java.lang.Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @java.lang.Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - *
-     * GrantX509Cert holds the proof that at least a threshold number of clients
-     * accepted the reencryption.
-     * For each client, there must exist a certificate that can be verified by the
-     * CA certificate from AuthX509Cert. Additionally, each client must sign the
-     * following message:
-     *   sha256( Secret | Ephemeral | Time )
-     * 
- * - * Protobuf type {@code calypso.GrantX509Cert} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:calypso.GrantX509Cert) - ch.epfl.dedis.lib.proto.Calypso.GrantX509CertOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantX509Cert_descriptor; - } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantX509Cert_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.class, ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.Builder.class); - } - - // Construct using ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - } - } - @java.lang.Override - public Builder clear() { - super.clear(); - secret_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000001); - certificates_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return ch.epfl.dedis.lib.proto.Calypso.internal_static_calypso_GrantX509Cert_descriptor; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance(); - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert build() { - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert buildPartial() { - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert result = new ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) != 0)) { - to_bitField0_ |= 0x00000001; - } - result.secret_ = secret_; - if (((bitField0_ & 0x00000002) != 0)) { - certificates_ = java.util.Collections.unmodifiableList(certificates_); - bitField0_ = (bitField0_ & ~0x00000002); - } - result.certificates_ = certificates_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert) { - return mergeFrom((ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert other) { - if (other == ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert.getDefaultInstance()) return this; - if (other.hasSecret()) { - setSecret(other.getSecret()); - } - if (!other.certificates_.isEmpty()) { - if (certificates_.isEmpty()) { - certificates_ = other.certificates_; - bitField0_ = (bitField0_ & ~0x00000002); - } else { - ensureCertificatesIsMutable(); - certificates_.addAll(other.certificates_); - } - onChanged(); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - if (!hasSecret()) { - return false; - } - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - private com.google.protobuf.ByteString secret_ = com.google.protobuf.ByteString.EMPTY; - /** - * required bytes secret = 1; - */ - public boolean hasSecret() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * required bytes secret = 1; - */ - public com.google.protobuf.ByteString getSecret() { - return secret_; - } - /** - * required bytes secret = 1; - */ - public Builder setSecret(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - secret_ = value; - onChanged(); - return this; - } - /** - * required bytes secret = 1; - */ - public Builder clearSecret() { - bitField0_ = (bitField0_ & ~0x00000001); - secret_ = getDefaultInstance().getSecret(); - onChanged(); - return this; - } - - private java.util.List certificates_ = java.util.Collections.emptyList(); - private void ensureCertificatesIsMutable() { - if (!((bitField0_ & 0x00000002) != 0)) { - certificates_ = new java.util.ArrayList(certificates_); - bitField0_ |= 0x00000002; - } - } - /** - * repeated bytes certificates = 2; - */ - public java.util.List - getCertificatesList() { - return ((bitField0_ & 0x00000002) != 0) ? - java.util.Collections.unmodifiableList(certificates_) : certificates_; - } - /** - * repeated bytes certificates = 2; - */ - public int getCertificatesCount() { - return certificates_.size(); - } - /** - * repeated bytes certificates = 2; - */ - public com.google.protobuf.ByteString getCertificates(int index) { - return certificates_.get(index); - } - /** - * repeated bytes certificates = 2; - */ - public Builder setCertificates( - int index, com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureCertificatesIsMutable(); - certificates_.set(index, value); - onChanged(); - return this; - } - /** - * repeated bytes certificates = 2; - */ - public Builder addCertificates(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureCertificatesIsMutable(); - certificates_.add(value); - onChanged(); - return this; - } - /** - * repeated bytes certificates = 2; - */ - public Builder addAllCertificates( - java.lang.Iterable values) { - ensureCertificatesIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, certificates_); - onChanged(); - return this; - } - /** - * repeated bytes certificates = 2; - */ - public Builder clearCertificates() { - certificates_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000002); - onChanged(); - return this; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:calypso.GrantX509Cert) - } - - // @@protoc_insertion_point(class_scope:calypso.GrantX509Cert) - private static final ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert(); - } - - public static ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public GrantX509Cert parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new GrantX509Cert(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - - } - private static final com.google.protobuf.Descriptors.Descriptor internal_static_calypso_Write_descriptor; private static final @@ -13287,36 +8572,6 @@ public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getDefaultInstanceForType() private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_calypso_LtsInstanceInfo_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor - internal_static_calypso_Auth_descriptor; - private static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_calypso_Auth_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor - internal_static_calypso_AuthByzCoin_descriptor; - private static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_calypso_AuthByzCoin_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor - internal_static_calypso_AuthX509Cert_descriptor; - private static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_calypso_AuthX509Cert_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor - internal_static_calypso_Grant_descriptor; - private static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_calypso_Grant_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor - internal_static_calypso_GrantByzCoin_descriptor; - private static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_calypso_GrantByzCoin_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor - internal_static_calypso_GrantX509Cert_descriptor; - private static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_calypso_GrantX509Cert_fieldAccessorTable; public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { @@ -13341,19 +8596,8 @@ public ch.epfl.dedis.lib.proto.Calypso.GrantX509Cert getDefaultInstanceForType() "\030\002 \002(\0132\016.byzcoin.Proof\"8\n\017DecryptKeyRepl" + "y\022\t\n\001c\030\001 \002(\014\022\017\n\007xhatenc\030\002 \002(\014\022\t\n\001x\030\003 \002(\014" + "\"\034\n\013GetLTSReply\022\r\n\005ltsid\030\001 \002(\014\"/\n\017LtsIns" + - "tanceInfo\022\034\n\006roster\030\001 \002(\0132\014.onet.Roster\"" + - "Z\n\004Auth\022%\n\007byzcoin\030\001 \001(\0132\024.calypso.AuthB" + - "yzCoin\022+\n\014authx509cert\030\002 \001(\0132\025.calypso.A" + - "uthX509Cert\"-\n\013AuthByzCoin\022\021\n\tbyzcoinid\030" + - "\001 \002(\014\022\013\n\003ttl\030\002 \002(\004\"-\n\014AuthX509Cert\022\n\n\002ca" + - "\030\001 \003(\014\022\021\n\tthreshold\030\002 \002(\021\"Y\n\005Grant\022&\n\007by" + - "zcoin\030\001 \001(\0132\025.calypso.GrantByzCoin\022(\n\010x5" + - "09cert\030\002 \001(\0132\026.calypso.GrantX509Cert\"K\n\014" + - "GrantByzCoin\022\035\n\005write\030\001 \002(\0132\016.byzcoin.Pr" + - "oof\022\034\n\004read\030\002 \002(\0132\016.byzcoin.Proof\"5\n\rGra" + - "ntX509Cert\022\016\n\006secret\030\001 \002(\014\022\024\n\014certificat" + - "es\030\002 \003(\014B\"\n\027ch.epfl.dedis.lib.protoB\007Cal" + - "ypso" + "tanceInfo\022\034\n\006roster\030\001 \002(\0132\014.onet.RosterB" + + "\"\n\027ch.epfl.dedis.lib.protoB\007Calypso" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { @@ -13441,42 +8685,6 @@ public com.google.protobuf.ExtensionRegistry assignDescriptors( com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_calypso_LtsInstanceInfo_descriptor, new java.lang.String[] { "Roster", }); - internal_static_calypso_Auth_descriptor = - getDescriptor().getMessageTypes().get(12); - internal_static_calypso_Auth_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_Auth_descriptor, - new java.lang.String[] { "Byzcoin", "Authx509Cert", }); - internal_static_calypso_AuthByzCoin_descriptor = - getDescriptor().getMessageTypes().get(13); - internal_static_calypso_AuthByzCoin_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_AuthByzCoin_descriptor, - new java.lang.String[] { "Byzcoinid", "Ttl", }); - internal_static_calypso_AuthX509Cert_descriptor = - getDescriptor().getMessageTypes().get(14); - internal_static_calypso_AuthX509Cert_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_AuthX509Cert_descriptor, - new java.lang.String[] { "Ca", "Threshold", }); - internal_static_calypso_Grant_descriptor = - getDescriptor().getMessageTypes().get(15); - internal_static_calypso_Grant_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_Grant_descriptor, - new java.lang.String[] { "Byzcoin", "X509Cert", }); - internal_static_calypso_GrantByzCoin_descriptor = - getDescriptor().getMessageTypes().get(16); - internal_static_calypso_GrantByzCoin_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_GrantByzCoin_descriptor, - new java.lang.String[] { "Write", "Read", }); - internal_static_calypso_GrantX509Cert_descriptor = - getDescriptor().getMessageTypes().get(17); - internal_static_calypso_GrantX509Cert_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_calypso_GrantX509Cert_descriptor, - new java.lang.String[] { "Secret", "Certificates", }); ch.epfl.dedis.lib.proto.ByzCoinProto.getDescriptor(); ch.epfl.dedis.lib.proto.OnetProto.getDescriptor(); } diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java new file mode 100644 index 0000000000..f2b1e40b9e --- /dev/null +++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java @@ -0,0 +1,7342 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ocs.proto + +package ch.epfl.dedis.lib.proto; + +public final class OCS { + private OCS() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + public interface CreateOCSOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.CreateOCS) + com.google.protobuf.MessageOrBuilder { + + /** + * required .onet.Roster roster = 1; + */ + boolean hasRoster(); + /** + * required .onet.Roster roster = 1; + */ + ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster(); + /** + * required .onet.Roster roster = 1; + */ + ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder(); + + /** + * required .ocs.Auth authentication = 2; + */ + boolean hasAuthentication(); + /** + * required .ocs.Auth authentication = 2; + */ + ch.epfl.dedis.lib.proto.OCS.Auth getAuthentication(); + /** + * required .ocs.Auth authentication = 2; + */ + ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder getAuthenticationOrBuilder(); + } + /** + *
+   * CreateOCS is sent to the service to request a new OCS cothority.
+   * 
+ * + * Protobuf type {@code ocs.CreateOCS} + */ + public static final class CreateOCS extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.CreateOCS) + CreateOCSOrBuilder { + private static final long serialVersionUID = 0L; + // Use CreateOCS.newBuilder() to construct. + private CreateOCS(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private CreateOCS() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CreateOCS( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = roster_.toBuilder(); + } + roster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(roster_); + roster_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + ch.epfl.dedis.lib.proto.OCS.Auth.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = authentication_.toBuilder(); + } + authentication_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Auth.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(authentication_); + authentication_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.CreateOCS.class, ch.epfl.dedis.lib.proto.OCS.CreateOCS.Builder.class); + } + + private int bitField0_; + public static final int ROSTER_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_; + /** + * required .onet.Roster roster = 1; + */ + public boolean hasRoster() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required .onet.Roster roster = 1; + */ + public ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster() { + return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; + } + /** + * required .onet.Roster roster = 1; + */ + public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() { + return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; + } + + public static final int AUTHENTICATION_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.Auth authentication_; + /** + * required .ocs.Auth authentication = 2; + */ + public boolean hasAuthentication() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .ocs.Auth authentication = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.Auth getAuthentication() { + return authentication_ == null ? ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance() : authentication_; + } + /** + * required .ocs.Auth authentication = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder getAuthenticationOrBuilder() { + return authentication_ == null ? ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance() : authentication_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasRoster()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasAuthentication()) { + memoizedIsInitialized = 0; + return false; + } + if (!getRoster().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getAuthentication().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getRoster()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getAuthentication()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getRoster()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getAuthentication()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCS)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.CreateOCS other = (ch.epfl.dedis.lib.proto.OCS.CreateOCS) obj; + + if (hasRoster() != other.hasRoster()) return false; + if (hasRoster()) { + if (!getRoster() + .equals(other.getRoster())) return false; + } + if (hasAuthentication() != other.hasAuthentication()) return false; + if (hasAuthentication()) { + if (!getAuthentication() + .equals(other.getAuthentication())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasRoster()) { + hash = (37 * hash) + ROSTER_FIELD_NUMBER; + hash = (53 * hash) + getRoster().hashCode(); + } + if (hasAuthentication()) { + hash = (37 * hash) + AUTHENTICATION_FIELD_NUMBER; + hash = (53 * hash) + getAuthentication().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.CreateOCS prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * CreateOCS is sent to the service to request a new OCS cothority.
+     * 
+ * + * Protobuf type {@code ocs.CreateOCS} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.CreateOCS) + ch.epfl.dedis.lib.proto.OCS.CreateOCSOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.CreateOCS.class, ch.epfl.dedis.lib.proto.OCS.CreateOCS.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.CreateOCS.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getRosterFieldBuilder(); + getAuthenticationFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (rosterBuilder_ == null) { + roster_ = null; + } else { + rosterBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (authenticationBuilder_ == null) { + authentication_ = null; + } else { + authenticationBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.CreateOCS getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.CreateOCS.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.CreateOCS build() { + ch.epfl.dedis.lib.proto.OCS.CreateOCS result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.CreateOCS buildPartial() { + ch.epfl.dedis.lib.proto.OCS.CreateOCS result = new ch.epfl.dedis.lib.proto.OCS.CreateOCS(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + if (rosterBuilder_ == null) { + result.roster_ = roster_; + } else { + result.roster_ = rosterBuilder_.build(); + } + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + if (authenticationBuilder_ == null) { + result.authentication_ = authentication_; + } else { + result.authentication_ = authenticationBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCS) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.CreateOCS)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.CreateOCS other) { + if (other == ch.epfl.dedis.lib.proto.OCS.CreateOCS.getDefaultInstance()) return this; + if (other.hasRoster()) { + mergeRoster(other.getRoster()); + } + if (other.hasAuthentication()) { + mergeAuthentication(other.getAuthentication()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasRoster()) { + return false; + } + if (!hasAuthentication()) { + return false; + } + if (!getRoster().isInitialized()) { + return false; + } + if (!getAuthentication().isInitialized()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.CreateOCS parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.CreateOCS) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> rosterBuilder_; + /** + * required .onet.Roster roster = 1; + */ + public boolean hasRoster() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required .onet.Roster roster = 1; + */ + public ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster() { + if (rosterBuilder_ == null) { + return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; + } else { + return rosterBuilder_.getMessage(); + } + } + /** + * required .onet.Roster roster = 1; + */ + public Builder setRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { + if (rosterBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + roster_ = value; + onChanged(); + } else { + rosterBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .onet.Roster roster = 1; + */ + public Builder setRoster( + ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder builderForValue) { + if (rosterBuilder_ == null) { + roster_ = builderForValue.build(); + onChanged(); + } else { + rosterBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .onet.Roster roster = 1; + */ + public Builder mergeRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { + if (rosterBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + roster_ != null && + roster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) { + roster_ = + ch.epfl.dedis.lib.proto.OnetProto.Roster.newBuilder(roster_).mergeFrom(value).buildPartial(); + } else { + roster_ = value; + } + onChanged(); + } else { + rosterBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .onet.Roster roster = 1; + */ + public Builder clearRoster() { + if (rosterBuilder_ == null) { + roster_ = null; + onChanged(); + } else { + rosterBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .onet.Roster roster = 1; + */ + public ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder getRosterBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getRosterFieldBuilder().getBuilder(); + } + /** + * required .onet.Roster roster = 1; + */ + public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() { + if (rosterBuilder_ != null) { + return rosterBuilder_.getMessageOrBuilder(); + } else { + return roster_ == null ? + ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; + } + } + /** + * required .onet.Roster roster = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> + getRosterFieldBuilder() { + if (rosterBuilder_ == null) { + rosterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder>( + getRoster(), + getParentForChildren(), + isClean()); + roster_ = null; + } + return rosterBuilder_; + } + + private ch.epfl.dedis.lib.proto.OCS.Auth authentication_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Auth, ch.epfl.dedis.lib.proto.OCS.Auth.Builder, ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder> authenticationBuilder_; + /** + * required .ocs.Auth authentication = 2; + */ + public boolean hasAuthentication() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .ocs.Auth authentication = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.Auth getAuthentication() { + if (authenticationBuilder_ == null) { + return authentication_ == null ? ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance() : authentication_; + } else { + return authenticationBuilder_.getMessage(); + } + } + /** + * required .ocs.Auth authentication = 2; + */ + public Builder setAuthentication(ch.epfl.dedis.lib.proto.OCS.Auth value) { + if (authenticationBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + authentication_ = value; + onChanged(); + } else { + authenticationBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.Auth authentication = 2; + */ + public Builder setAuthentication( + ch.epfl.dedis.lib.proto.OCS.Auth.Builder builderForValue) { + if (authenticationBuilder_ == null) { + authentication_ = builderForValue.build(); + onChanged(); + } else { + authenticationBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.Auth authentication = 2; + */ + public Builder mergeAuthentication(ch.epfl.dedis.lib.proto.OCS.Auth value) { + if (authenticationBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + authentication_ != null && + authentication_ != ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance()) { + authentication_ = + ch.epfl.dedis.lib.proto.OCS.Auth.newBuilder(authentication_).mergeFrom(value).buildPartial(); + } else { + authentication_ = value; + } + onChanged(); + } else { + authenticationBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.Auth authentication = 2; + */ + public Builder clearAuthentication() { + if (authenticationBuilder_ == null) { + authentication_ = null; + onChanged(); + } else { + authenticationBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * required .ocs.Auth authentication = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.Auth.Builder getAuthenticationBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getAuthenticationFieldBuilder().getBuilder(); + } + /** + * required .ocs.Auth authentication = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder getAuthenticationOrBuilder() { + if (authenticationBuilder_ != null) { + return authenticationBuilder_.getMessageOrBuilder(); + } else { + return authentication_ == null ? + ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance() : authentication_; + } + } + /** + * required .ocs.Auth authentication = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Auth, ch.epfl.dedis.lib.proto.OCS.Auth.Builder, ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder> + getAuthenticationFieldBuilder() { + if (authenticationBuilder_ == null) { + authenticationBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Auth, ch.epfl.dedis.lib.proto.OCS.Auth.Builder, ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder>( + getAuthentication(), + getParentForChildren(), + isClean()); + authentication_ = null; + } + return authenticationBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.CreateOCS) + } + + // @@protoc_insertion_point(class_scope:ocs.CreateOCS) + private static final ch.epfl.dedis.lib.proto.OCS.CreateOCS DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.CreateOCS(); + } + + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public CreateOCS parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CreateOCS(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.CreateOCS getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface CreateOCSReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.CreateOCSReply) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes x = 1; + */ + boolean hasX(); + /** + * required bytes x = 1; + */ + com.google.protobuf.ByteString getX(); + + /** + * required bytes sig = 2; + */ + boolean hasSig(); + /** + * required bytes sig = 2; + */ + com.google.protobuf.ByteString getSig(); + } + /** + *
+   * CreateOCSReply is the reply sent by the conode if the OCS has been
+   * setup correctly. It contains the ID of the OCS, which is the binary
+   * representation of the aggregate public key. It also has the Sig, which
+   * is the collective signature of all nodes on the aggregate public key
+   * and the authentication.
+   * 
+ * + * Protobuf type {@code ocs.CreateOCSReply} + */ + public static final class CreateOCSReply extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.CreateOCSReply) + CreateOCSReplyOrBuilder { + private static final long serialVersionUID = 0L; + // Use CreateOCSReply.newBuilder() to construct. + private CreateOCSReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private CreateOCSReply() { + x_ = com.google.protobuf.ByteString.EMPTY; + sig_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CreateOCSReply( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + x_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + sig_ = input.readBytes(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.class, ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.Builder.class); + } + + private int bitField0_; + public static final int X_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString x_; + /** + * required bytes x = 1; + */ + public boolean hasX() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes x = 1; + */ + public com.google.protobuf.ByteString getX() { + return x_; + } + + public static final int SIG_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString sig_; + /** + * required bytes sig = 2; + */ + public boolean hasSig() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required bytes sig = 2; + */ + public com.google.protobuf.ByteString getSig() { + return sig_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasX()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasSig()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, x_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeBytes(2, sig_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, x_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, sig_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCSReply)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply other = (ch.epfl.dedis.lib.proto.OCS.CreateOCSReply) obj; + + if (hasX() != other.hasX()) return false; + if (hasX()) { + if (!getX() + .equals(other.getX())) return false; + } + if (hasSig() != other.hasSig()) return false; + if (hasSig()) { + if (!getSig() + .equals(other.getSig())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasX()) { + hash = (37 * hash) + X_FIELD_NUMBER; + hash = (53 * hash) + getX().hashCode(); + } + if (hasSig()) { + hash = (37 * hash) + SIG_FIELD_NUMBER; + hash = (53 * hash) + getSig().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.CreateOCSReply prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * CreateOCSReply is the reply sent by the conode if the OCS has been
+     * setup correctly. It contains the ID of the OCS, which is the binary
+     * representation of the aggregate public key. It also has the Sig, which
+     * is the collective signature of all nodes on the aggregate public key
+     * and the authentication.
+     * 
+ * + * Protobuf type {@code ocs.CreateOCSReply} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.CreateOCSReply) + ch.epfl.dedis.lib.proto.OCS.CreateOCSReplyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.class, ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + x_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + sig_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply build() { + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply buildPartial() { + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply result = new ch.epfl.dedis.lib.proto.OCS.CreateOCSReply(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.x_ = x_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.sig_ = sig_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCSReply) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.CreateOCSReply)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.CreateOCSReply other) { + if (other == ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.getDefaultInstance()) return this; + if (other.hasX()) { + setX(other.getX()); + } + if (other.hasSig()) { + setSig(other.getSig()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasX()) { + return false; + } + if (!hasSig()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.CreateOCSReply) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString x_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes x = 1; + */ + public boolean hasX() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes x = 1; + */ + public com.google.protobuf.ByteString getX() { + return x_; + } + /** + * required bytes x = 1; + */ + public Builder setX(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + x_ = value; + onChanged(); + return this; + } + /** + * required bytes x = 1; + */ + public Builder clearX() { + bitField0_ = (bitField0_ & ~0x00000001); + x_ = getDefaultInstance().getX(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString sig_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes sig = 2; + */ + public boolean hasSig() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required bytes sig = 2; + */ + public com.google.protobuf.ByteString getSig() { + return sig_; + } + /** + * required bytes sig = 2; + */ + public Builder setSig(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + sig_ = value; + onChanged(); + return this; + } + /** + * required bytes sig = 2; + */ + public Builder clearSig() { + bitField0_ = (bitField0_ & ~0x00000002); + sig_ = getDefaultInstance().getSig(); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.CreateOCSReply) + } + + // @@protoc_insertion_point(class_scope:ocs.CreateOCSReply) + private static final ch.epfl.dedis.lib.proto.OCS.CreateOCSReply DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.CreateOCSReply(); + } + + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public CreateOCSReply parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CreateOCSReply(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ReencryptOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.Reencrypt) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes x = 1; + */ + boolean hasX(); + /** + * required bytes x = 1; + */ + com.google.protobuf.ByteString getX(); + + /** + * required .ocs.Grant grant = 2; + */ + boolean hasGrant(); + /** + * required .ocs.Grant grant = 2; + */ + ch.epfl.dedis.lib.proto.OCS.Grant getGrant(); + /** + * required .ocs.Grant grant = 2; + */ + ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder getGrantOrBuilder(); + } + /** + *
+   * Reencrypt is sent to the service to request a re-encryption of the
+   * secret given in Grant. Grant must also contain the proof that the
+   * request is valid, as well as the ephemeral key, to which the secret
+   * will be re-encrypted.
+   * 
+ * + * Protobuf type {@code ocs.Reencrypt} + */ + public static final class Reencrypt extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.Reencrypt) + ReencryptOrBuilder { + private static final long serialVersionUID = 0L; + // Use Reencrypt.newBuilder() to construct. + private Reencrypt(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Reencrypt() { + x_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Reencrypt( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + x_ = input.readBytes(); + break; + } + case 18: { + ch.epfl.dedis.lib.proto.OCS.Grant.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = grant_.toBuilder(); + } + grant_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Grant.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(grant_); + grant_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Reencrypt.class, ch.epfl.dedis.lib.proto.OCS.Reencrypt.Builder.class); + } + + private int bitField0_; + public static final int X_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString x_; + /** + * required bytes x = 1; + */ + public boolean hasX() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes x = 1; + */ + public com.google.protobuf.ByteString getX() { + return x_; + } + + public static final int GRANT_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.Grant grant_; + /** + * required .ocs.Grant grant = 2; + */ + public boolean hasGrant() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .ocs.Grant grant = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.Grant getGrant() { + return grant_ == null ? ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance() : grant_; + } + /** + * required .ocs.Grant grant = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder getGrantOrBuilder() { + return grant_ == null ? ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance() : grant_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasX()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasGrant()) { + memoizedIsInitialized = 0; + return false; + } + if (!getGrant().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, x_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getGrant()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, x_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getGrant()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Reencrypt)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.Reencrypt other = (ch.epfl.dedis.lib.proto.OCS.Reencrypt) obj; + + if (hasX() != other.hasX()) return false; + if (hasX()) { + if (!getX() + .equals(other.getX())) return false; + } + if (hasGrant() != other.hasGrant()) return false; + if (hasGrant()) { + if (!getGrant() + .equals(other.getGrant())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasX()) { + hash = (37 * hash) + X_FIELD_NUMBER; + hash = (53 * hash) + getX().hashCode(); + } + if (hasGrant()) { + hash = (37 * hash) + GRANT_FIELD_NUMBER; + hash = (53 * hash) + getGrant().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Reencrypt prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Reencrypt is sent to the service to request a re-encryption of the
+     * secret given in Grant. Grant must also contain the proof that the
+     * request is valid, as well as the ephemeral key, to which the secret
+     * will be re-encrypted.
+     * 
+ * + * Protobuf type {@code ocs.Reencrypt} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.Reencrypt) + ch.epfl.dedis.lib.proto.OCS.ReencryptOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Reencrypt.class, ch.epfl.dedis.lib.proto.OCS.Reencrypt.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.Reencrypt.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getGrantFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + x_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + if (grantBuilder_ == null) { + grant_ = null; + } else { + grantBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reencrypt getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.Reencrypt.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reencrypt build() { + ch.epfl.dedis.lib.proto.OCS.Reencrypt result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reencrypt buildPartial() { + ch.epfl.dedis.lib.proto.OCS.Reencrypt result = new ch.epfl.dedis.lib.proto.OCS.Reencrypt(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.x_ = x_; + if (((from_bitField0_ & 0x00000002) != 0)) { + if (grantBuilder_ == null) { + result.grant_ = grant_; + } else { + result.grant_ = grantBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.Reencrypt) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Reencrypt)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Reencrypt other) { + if (other == ch.epfl.dedis.lib.proto.OCS.Reencrypt.getDefaultInstance()) return this; + if (other.hasX()) { + setX(other.getX()); + } + if (other.hasGrant()) { + mergeGrant(other.getGrant()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasX()) { + return false; + } + if (!hasGrant()) { + return false; + } + if (!getGrant().isInitialized()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.Reencrypt parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Reencrypt) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString x_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes x = 1; + */ + public boolean hasX() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes x = 1; + */ + public com.google.protobuf.ByteString getX() { + return x_; + } + /** + * required bytes x = 1; + */ + public Builder setX(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + x_ = value; + onChanged(); + return this; + } + /** + * required bytes x = 1; + */ + public Builder clearX() { + bitField0_ = (bitField0_ & ~0x00000001); + x_ = getDefaultInstance().getX(); + onChanged(); + return this; + } + + private ch.epfl.dedis.lib.proto.OCS.Grant grant_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Grant, ch.epfl.dedis.lib.proto.OCS.Grant.Builder, ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder> grantBuilder_; + /** + * required .ocs.Grant grant = 2; + */ + public boolean hasGrant() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .ocs.Grant grant = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.Grant getGrant() { + if (grantBuilder_ == null) { + return grant_ == null ? ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance() : grant_; + } else { + return grantBuilder_.getMessage(); + } + } + /** + * required .ocs.Grant grant = 2; + */ + public Builder setGrant(ch.epfl.dedis.lib.proto.OCS.Grant value) { + if (grantBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + grant_ = value; + onChanged(); + } else { + grantBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.Grant grant = 2; + */ + public Builder setGrant( + ch.epfl.dedis.lib.proto.OCS.Grant.Builder builderForValue) { + if (grantBuilder_ == null) { + grant_ = builderForValue.build(); + onChanged(); + } else { + grantBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.Grant grant = 2; + */ + public Builder mergeGrant(ch.epfl.dedis.lib.proto.OCS.Grant value) { + if (grantBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + grant_ != null && + grant_ != ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance()) { + grant_ = + ch.epfl.dedis.lib.proto.OCS.Grant.newBuilder(grant_).mergeFrom(value).buildPartial(); + } else { + grant_ = value; + } + onChanged(); + } else { + grantBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.Grant grant = 2; + */ + public Builder clearGrant() { + if (grantBuilder_ == null) { + grant_ = null; + onChanged(); + } else { + grantBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * required .ocs.Grant grant = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.Grant.Builder getGrantBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getGrantFieldBuilder().getBuilder(); + } + /** + * required .ocs.Grant grant = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder getGrantOrBuilder() { + if (grantBuilder_ != null) { + return grantBuilder_.getMessageOrBuilder(); + } else { + return grant_ == null ? + ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance() : grant_; + } + } + /** + * required .ocs.Grant grant = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Grant, ch.epfl.dedis.lib.proto.OCS.Grant.Builder, ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder> + getGrantFieldBuilder() { + if (grantBuilder_ == null) { + grantBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Grant, ch.epfl.dedis.lib.proto.OCS.Grant.Builder, ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder>( + getGrant(), + getParentForChildren(), + isClean()); + grant_ = null; + } + return grantBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.Reencrypt) + } + + // @@protoc_insertion_point(class_scope:ocs.Reencrypt) + private static final ch.epfl.dedis.lib.proto.OCS.Reencrypt DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Reencrypt(); + } + + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Reencrypt parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Reencrypt(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reencrypt getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ReencryptReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.ReencryptReply) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes xhat = 1; + */ + boolean hasXhat(); + /** + * required bytes xhat = 1; + */ + com.google.protobuf.ByteString getXhat(); + } + /** + *
+   * ReencryptReply is the reply if the re-encryption is successful, and
+   * it contains XHat, which is the secret re-encrypted to the ephemeral
+   * key given in Grant.
+   * 
+ * + * Protobuf type {@code ocs.ReencryptReply} + */ + public static final class ReencryptReply extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.ReencryptReply) + ReencryptReplyOrBuilder { + private static final long serialVersionUID = 0L; + // Use ReencryptReply.newBuilder() to construct. + private ReencryptReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private ReencryptReply() { + xhat_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ReencryptReply( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + xhat_ = input.readBytes(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.ReencryptReply.class, ch.epfl.dedis.lib.proto.OCS.ReencryptReply.Builder.class); + } + + private int bitField0_; + public static final int XHAT_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString xhat_; + /** + * required bytes xhat = 1; + */ + public boolean hasXhat() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes xhat = 1; + */ + public com.google.protobuf.ByteString getXhat() { + return xhat_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasXhat()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, xhat_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, xhat_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.ReencryptReply)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.ReencryptReply other = (ch.epfl.dedis.lib.proto.OCS.ReencryptReply) obj; + + if (hasXhat() != other.hasXhat()) return false; + if (hasXhat()) { + if (!getXhat() + .equals(other.getXhat())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasXhat()) { + hash = (37 * hash) + XHAT_FIELD_NUMBER; + hash = (53 * hash) + getXhat().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.ReencryptReply prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * ReencryptReply is the reply if the re-encryption is successful, and
+     * it contains XHat, which is the secret re-encrypted to the ephemeral
+     * key given in Grant.
+     * 
+ * + * Protobuf type {@code ocs.ReencryptReply} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.ReencryptReply) + ch.epfl.dedis.lib.proto.OCS.ReencryptReplyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.ReencryptReply.class, ch.epfl.dedis.lib.proto.OCS.ReencryptReply.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.ReencryptReply.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + xhat_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReencryptReply getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.ReencryptReply.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReencryptReply build() { + ch.epfl.dedis.lib.proto.OCS.ReencryptReply result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReencryptReply buildPartial() { + ch.epfl.dedis.lib.proto.OCS.ReencryptReply result = new ch.epfl.dedis.lib.proto.OCS.ReencryptReply(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.xhat_ = xhat_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.ReencryptReply) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.ReencryptReply)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.ReencryptReply other) { + if (other == ch.epfl.dedis.lib.proto.OCS.ReencryptReply.getDefaultInstance()) return this; + if (other.hasXhat()) { + setXhat(other.getXhat()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasXhat()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.ReencryptReply parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.ReencryptReply) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString xhat_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes xhat = 1; + */ + public boolean hasXhat() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes xhat = 1; + */ + public com.google.protobuf.ByteString getXhat() { + return xhat_; + } + /** + * required bytes xhat = 1; + */ + public Builder setXhat(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + xhat_ = value; + onChanged(); + return this; + } + /** + * required bytes xhat = 1; + */ + public Builder clearXhat() { + bitField0_ = (bitField0_ & ~0x00000001); + xhat_ = getDefaultInstance().getXhat(); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.ReencryptReply) + } + + // @@protoc_insertion_point(class_scope:ocs.ReencryptReply) + private static final ch.epfl.dedis.lib.proto.OCS.ReencryptReply DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.ReencryptReply(); + } + + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ReencryptReply parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ReencryptReply(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReencryptReply getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AuthOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.Auth) + com.google.protobuf.MessageOrBuilder { + + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + boolean hasByzcoin(); + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getByzcoin(); + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder getByzcoinOrBuilder(); + + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + boolean hasAuthx509Cert(); + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getAuthx509Cert(); + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder getAuthx509CertOrBuilder(); + } + /** + *
+   * Auth holds all possible authentication structures. When using it to call
+   * Authorise, only one of the fields must be non-nil.
+   * 
+ * + * Protobuf type {@code ocs.Auth} + */ + public static final class Auth extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.Auth) + AuthOrBuilder { + private static final long serialVersionUID = 0L; + // Use Auth.newBuilder() to construct. + private Auth(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Auth() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Auth( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = byzcoin_.toBuilder(); + } + byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(byzcoin_); + byzcoin_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = authx509Cert_.toBuilder(); + } + authx509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(authx509Cert_); + authx509Cert_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Auth_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Auth_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Auth.class, ch.epfl.dedis.lib.proto.OCS.Auth.Builder.class); + } + + private int bitField0_; + public static final int BYZCOIN_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OCS.AuthByzCoin byzcoin_; + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getByzcoin() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance() : byzcoin_; + } + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder getByzcoinOrBuilder() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance() : byzcoin_; + } + + public static final int AUTHX509CERT_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.AuthX509Cert authx509Cert_; + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + public boolean hasAuthx509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getAuthx509Cert() { + return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance() : authx509Cert_; + } + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder getAuthx509CertOrBuilder() { + return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance() : authx509Cert_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasAuthx509Cert()) { + if (!getAuthx509Cert().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getAuthx509Cert()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getAuthx509Cert()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Auth)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.Auth other = (ch.epfl.dedis.lib.proto.OCS.Auth) obj; + + if (hasByzcoin() != other.hasByzcoin()) return false; + if (hasByzcoin()) { + if (!getByzcoin() + .equals(other.getByzcoin())) return false; + } + if (hasAuthx509Cert() != other.hasAuthx509Cert()) return false; + if (hasAuthx509Cert()) { + if (!getAuthx509Cert() + .equals(other.getAuthx509Cert())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasByzcoin()) { + hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; + hash = (53 * hash) + getByzcoin().hashCode(); + } + if (hasAuthx509Cert()) { + hash = (37 * hash) + AUTHX509CERT_FIELD_NUMBER; + hash = (53 * hash) + getAuthx509Cert().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Auth parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Auth parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Auth prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Auth holds all possible authentication structures. When using it to call
+     * Authorise, only one of the fields must be non-nil.
+     * 
+ * + * Protobuf type {@code ocs.Auth} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.Auth) + ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Auth_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Auth_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Auth.class, ch.epfl.dedis.lib.proto.OCS.Auth.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.Auth.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getByzcoinFieldBuilder(); + getAuthx509CertFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (authx509CertBuilder_ == null) { + authx509Cert_ = null; + } else { + authx509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Auth_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Auth getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Auth build() { + ch.epfl.dedis.lib.proto.OCS.Auth result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Auth buildPartial() { + ch.epfl.dedis.lib.proto.OCS.Auth result = new ch.epfl.dedis.lib.proto.OCS.Auth(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + if (byzcoinBuilder_ == null) { + result.byzcoin_ = byzcoin_; + } else { + result.byzcoin_ = byzcoinBuilder_.build(); + } + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + if (authx509CertBuilder_ == null) { + result.authx509Cert_ = authx509Cert_; + } else { + result.authx509Cert_ = authx509CertBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.Auth) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Auth)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Auth other) { + if (other == ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance()) return this; + if (other.hasByzcoin()) { + mergeByzcoin(other.getByzcoin()); + } + if (other.hasAuthx509Cert()) { + mergeAuthx509Cert(other.getAuthx509Cert()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + return false; + } + } + if (hasAuthx509Cert()) { + if (!getAuthx509Cert().isInitialized()) { + return false; + } + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.Auth parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Auth) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private ch.epfl.dedis.lib.proto.OCS.AuthByzCoin byzcoin_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder> byzcoinBuilder_; + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getByzcoin() { + if (byzcoinBuilder_ == null) { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance() : byzcoin_; + } else { + return byzcoinBuilder_.getMessage(); + } + } + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthByzCoin value) { + if (byzcoinBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + byzcoin_ = value; + onChanged(); + } else { + byzcoinBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + public Builder setByzcoin( + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder builderForValue) { + if (byzcoinBuilder_ == null) { + byzcoin_ = builderForValue.build(); + onChanged(); + } else { + byzcoinBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthByzCoin value) { + if (byzcoinBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + byzcoin_ != null && + byzcoin_ != ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance()) { + byzcoin_ = + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); + } else { + byzcoin_ = value; + } + onChanged(); + } else { + byzcoinBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + public Builder clearByzcoin() { + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + onChanged(); + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder getByzcoinBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getByzcoinFieldBuilder().getBuilder(); + } + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder getByzcoinOrBuilder() { + if (byzcoinBuilder_ != null) { + return byzcoinBuilder_.getMessageOrBuilder(); + } else { + return byzcoin_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance() : byzcoin_; + } + } + /** + * optional .ocs.AuthByzCoin byzcoin = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder> + getByzcoinFieldBuilder() { + if (byzcoinBuilder_ == null) { + byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder>( + getByzcoin(), + getParentForChildren(), + isClean()); + byzcoin_ = null; + } + return byzcoinBuilder_; + } + + private ch.epfl.dedis.lib.proto.OCS.AuthX509Cert authx509Cert_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder> authx509CertBuilder_; + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + public boolean hasAuthx509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getAuthx509Cert() { + if (authx509CertBuilder_ == null) { + return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance() : authx509Cert_; + } else { + return authx509CertBuilder_.getMessage(); + } + } + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + public Builder setAuthx509Cert(ch.epfl.dedis.lib.proto.OCS.AuthX509Cert value) { + if (authx509CertBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + authx509Cert_ = value; + onChanged(); + } else { + authx509CertBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + public Builder setAuthx509Cert( + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder builderForValue) { + if (authx509CertBuilder_ == null) { + authx509Cert_ = builderForValue.build(); + onChanged(); + } else { + authx509CertBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + public Builder mergeAuthx509Cert(ch.epfl.dedis.lib.proto.OCS.AuthX509Cert value) { + if (authx509CertBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + authx509Cert_ != null && + authx509Cert_ != ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance()) { + authx509Cert_ = + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.newBuilder(authx509Cert_).mergeFrom(value).buildPartial(); + } else { + authx509Cert_ = value; + } + onChanged(); + } else { + authx509CertBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + public Builder clearAuthx509Cert() { + if (authx509CertBuilder_ == null) { + authx509Cert_ = null; + onChanged(); + } else { + authx509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder getAuthx509CertBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getAuthx509CertFieldBuilder().getBuilder(); + } + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder getAuthx509CertOrBuilder() { + if (authx509CertBuilder_ != null) { + return authx509CertBuilder_.getMessageOrBuilder(); + } else { + return authx509Cert_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance() : authx509Cert_; + } + } + /** + * optional .ocs.AuthX509Cert authx509cert = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder> + getAuthx509CertFieldBuilder() { + if (authx509CertBuilder_ == null) { + authx509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder>( + getAuthx509Cert(), + getParentForChildren(), + isClean()); + authx509Cert_ = null; + } + return authx509CertBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.Auth) + } + + // @@protoc_insertion_point(class_scope:ocs.Auth) + private static final ch.epfl.dedis.lib.proto.OCS.Auth DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Auth(); + } + + public static ch.epfl.dedis.lib.proto.OCS.Auth getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Auth parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Auth(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Auth getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AuthByzCoinOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthByzCoin) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes byzcoinid = 1; + */ + boolean hasByzcoinid(); + /** + * required bytes byzcoinid = 1; + */ + com.google.protobuf.ByteString getByzcoinid(); + + /** + * required uint64 ttl = 2; + */ + boolean hasTtl(); + /** + * required uint64 ttl = 2; + */ + long getTtl(); + } + /** + *
+   * AuthByzCoin holds the information necessary to authenticate a byzcoin request.
+   * In the ByzCoin model, all requests are valid as long as they are stored in the
+   * blockchain with the given ID.
+   * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+   * 
+ * + * Protobuf type {@code ocs.AuthByzCoin} + */ + public static final class AuthByzCoin extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.AuthByzCoin) + AuthByzCoinOrBuilder { + private static final long serialVersionUID = 0L; + // Use AuthByzCoin.newBuilder() to construct. + private AuthByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private AuthByzCoin() { + byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AuthByzCoin( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + byzcoinid_ = input.readBytes(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + ttl_ = input.readUInt64(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder.class); + } + + private int bitField0_; + public static final int BYZCOINID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString byzcoinid_; + /** + * required bytes byzcoinid = 1; + */ + public boolean hasByzcoinid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes byzcoinid = 1; + */ + public com.google.protobuf.ByteString getByzcoinid() { + return byzcoinid_; + } + + public static final int TTL_FIELD_NUMBER = 2; + private long ttl_; + /** + * required uint64 ttl = 2; + */ + public boolean hasTtl() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required uint64 ttl = 2; + */ + public long getTtl() { + return ttl_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasByzcoinid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTtl()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, byzcoinid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeUInt64(2, ttl_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, byzcoinid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(2, ttl_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthByzCoin)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin other = (ch.epfl.dedis.lib.proto.OCS.AuthByzCoin) obj; + + if (hasByzcoinid() != other.hasByzcoinid()) return false; + if (hasByzcoinid()) { + if (!getByzcoinid() + .equals(other.getByzcoinid())) return false; + } + if (hasTtl() != other.hasTtl()) return false; + if (hasTtl()) { + if (getTtl() + != other.getTtl()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasByzcoinid()) { + hash = (37 * hash) + BYZCOINID_FIELD_NUMBER; + hash = (53 * hash) + getByzcoinid().hashCode(); + } + if (hasTtl()) { + hash = (37 * hash) + TTL_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getTtl()); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthByzCoin prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * AuthByzCoin holds the information necessary to authenticate a byzcoin request.
+     * In the ByzCoin model, all requests are valid as long as they are stored in the
+     * blockchain with the given ID.
+     * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+     * 
+ * + * Protobuf type {@code ocs.AuthByzCoin} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.AuthByzCoin) + ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + ttl_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthByzCoin_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin build() { + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin result = new ch.epfl.dedis.lib.proto.OCS.AuthByzCoin(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.byzcoinid_ = byzcoinid_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.ttl_ = ttl_; + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthByzCoin) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthByzCoin)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthByzCoin other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance()) return this; + if (other.hasByzcoinid()) { + setByzcoinid(other.getByzcoinid()); + } + if (other.hasTtl()) { + setTtl(other.getTtl()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasByzcoinid()) { + return false; + } + if (!hasTtl()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthByzCoin) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes byzcoinid = 1; + */ + public boolean hasByzcoinid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes byzcoinid = 1; + */ + public com.google.protobuf.ByteString getByzcoinid() { + return byzcoinid_; + } + /** + * required bytes byzcoinid = 1; + */ + public Builder setByzcoinid(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + byzcoinid_ = value; + onChanged(); + return this; + } + /** + * required bytes byzcoinid = 1; + */ + public Builder clearByzcoinid() { + bitField0_ = (bitField0_ & ~0x00000001); + byzcoinid_ = getDefaultInstance().getByzcoinid(); + onChanged(); + return this; + } + + private long ttl_ ; + /** + * required uint64 ttl = 2; + */ + public boolean hasTtl() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required uint64 ttl = 2; + */ + public long getTtl() { + return ttl_; + } + /** + * required uint64 ttl = 2; + */ + public Builder setTtl(long value) { + bitField0_ |= 0x00000002; + ttl_ = value; + onChanged(); + return this; + } + /** + * required uint64 ttl = 2; + */ + public Builder clearTtl() { + bitField0_ = (bitField0_ & ~0x00000002); + ttl_ = 0L; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.AuthByzCoin) + } + + // @@protoc_insertion_point(class_scope:ocs.AuthByzCoin) + private static final ch.epfl.dedis.lib.proto.OCS.AuthByzCoin DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthByzCoin(); + } + + public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public AuthByzCoin parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AuthByzCoin(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AuthX509CertOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthX509Cert) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + java.util.List getCaList(); + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + int getCaCount(); + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + com.google.protobuf.ByteString getCa(int index); + + /** + * required sint32 threshold = 2; + */ + boolean hasThreshold(); + /** + * required sint32 threshold = 2; + */ + int getThreshold(); + } + /** + *
+   * AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
+   * request. In its simplest form, it is simply the CA that will have to sign the
+   * certificates of the requesters.
+   * The Threshold indicates how many clients must have signed the request before it
+   * is accepted.
+   * 
+ * + * Protobuf type {@code ocs.AuthX509Cert} + */ + public static final class AuthX509Cert extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.AuthX509Cert) + AuthX509CertOrBuilder { + private static final long serialVersionUID = 0L; + // Use AuthX509Cert.newBuilder() to construct. + private AuthX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private AuthX509Cert() { + ca_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AuthX509Cert( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + ca_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + ca_.add(input.readBytes()); + break; + } + case 16: { + bitField0_ |= 0x00000001; + threshold_ = input.readSInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + ca_ = java.util.Collections.unmodifiableList(ca_); // C + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthX509Cert_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder.class); + } + + private int bitField0_; + public static final int CA_FIELD_NUMBER = 1; + private java.util.List ca_; + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public java.util.List + getCaList() { + return ca_; + } + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public int getCaCount() { + return ca_.size(); + } + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public com.google.protobuf.ByteString getCa(int index) { + return ca_.get(index); + } + + public static final int THRESHOLD_FIELD_NUMBER = 2; + private int threshold_; + /** + * required sint32 threshold = 2; + */ + public boolean hasThreshold() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required sint32 threshold = 2; + */ + public int getThreshold() { + return threshold_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasThreshold()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < ca_.size(); i++) { + output.writeBytes(1, ca_.get(i)); + } + if (((bitField0_ & 0x00000001) != 0)) { + output.writeSInt32(2, threshold_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < ca_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(ca_.get(i)); + } + size += dataSize; + size += 1 * getCaList().size(); + } + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeSInt32Size(2, threshold_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthX509Cert)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert other = (ch.epfl.dedis.lib.proto.OCS.AuthX509Cert) obj; + + if (!getCaList() + .equals(other.getCaList())) return false; + if (hasThreshold() != other.hasThreshold()) return false; + if (hasThreshold()) { + if (getThreshold() + != other.getThreshold()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getCaCount() > 0) { + hash = (37 * hash) + CA_FIELD_NUMBER; + hash = (53 * hash) + getCaList().hashCode(); + } + if (hasThreshold()) { + hash = (37 * hash) + THRESHOLD_FIELD_NUMBER; + hash = (53 * hash) + getThreshold(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthX509Cert prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
+     * request. In its simplest form, it is simply the CA that will have to sign the
+     * certificates of the requesters.
+     * The Threshold indicates how many clients must have signed the request before it
+     * is accepted.
+     * 
+ * + * Protobuf type {@code ocs.AuthX509Cert} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.AuthX509Cert) + ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthX509Cert_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + ca_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + threshold_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthX509Cert_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert build() { + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert result = new ch.epfl.dedis.lib.proto.OCS.AuthX509Cert(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((bitField0_ & 0x00000001) != 0)) { + ca_ = java.util.Collections.unmodifiableList(ca_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.ca_ = ca_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.threshold_ = threshold_; + to_bitField0_ |= 0x00000001; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthX509Cert) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthX509Cert)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthX509Cert other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance()) return this; + if (!other.ca_.isEmpty()) { + if (ca_.isEmpty()) { + ca_ = other.ca_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureCaIsMutable(); + ca_.addAll(other.ca_); + } + onChanged(); + } + if (other.hasThreshold()) { + setThreshold(other.getThreshold()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasThreshold()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthX509Cert) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.util.List ca_ = java.util.Collections.emptyList(); + private void ensureCaIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + ca_ = new java.util.ArrayList(ca_); + bitField0_ |= 0x00000001; + } + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public java.util.List + getCaList() { + return ((bitField0_ & 0x00000001) != 0) ? + java.util.Collections.unmodifiableList(ca_) : ca_; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public int getCaCount() { + return ca_.size(); + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public com.google.protobuf.ByteString getCa(int index) { + return ca_.get(index); + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder setCa( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCaIsMutable(); + ca_.set(index, value); + onChanged(); + return this; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder addCa(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCaIsMutable(); + ca_.add(value); + onChanged(); + return this; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder addAllCa( + java.lang.Iterable values) { + ensureCaIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, ca_); + onChanged(); + return this; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder clearCa() { + ca_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + + private int threshold_ ; + /** + * required sint32 threshold = 2; + */ + public boolean hasThreshold() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required sint32 threshold = 2; + */ + public int getThreshold() { + return threshold_; + } + /** + * required sint32 threshold = 2; + */ + public Builder setThreshold(int value) { + bitField0_ |= 0x00000002; + threshold_ = value; + onChanged(); + return this; + } + /** + * required sint32 threshold = 2; + */ + public Builder clearThreshold() { + bitField0_ = (bitField0_ & ~0x00000002); + threshold_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.AuthX509Cert) + } + + // @@protoc_insertion_point(class_scope:ocs.AuthX509Cert) + private static final ch.epfl.dedis.lib.proto.OCS.AuthX509Cert DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthX509Cert(); + } + + public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public AuthX509Cert parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AuthX509Cert(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface GrantOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.Grant) + com.google.protobuf.MessageOrBuilder { + + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + boolean hasByzcoin(); + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getByzcoin(); + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder getByzcoinOrBuilder(); + + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + boolean hasX509Cert(); + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getX509Cert(); + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder getX509CertOrBuilder(); + } + /** + *
+   * Grant holds one of the possible grant proofs for a reencryption request. Each
+   * grant proof must hold the secret to be reencrypted, the ephemeral key, as well
+   * as the proof itself that the request is valid. For each of the authentication
+   * schemes, this proof will be different.
+   * 
+ * + * Protobuf type {@code ocs.Grant} + */ + public static final class Grant extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.Grant) + GrantOrBuilder { + private static final long serialVersionUID = 0L; + // Use Grant.newBuilder() to construct. + private Grant(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Grant() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Grant( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = byzcoin_.toBuilder(); + } + byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(byzcoin_); + byzcoin_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = x509Cert_.toBuilder(); + } + x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(x509Cert_); + x509Cert_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Grant_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Grant_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Grant.class, ch.epfl.dedis.lib.proto.OCS.Grant.Builder.class); + } + + private int bitField0_; + public static final int BYZCOIN_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OCS.GrantByzCoin byzcoin_; + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getByzcoin() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance() : byzcoin_; + } + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder getByzcoinOrBuilder() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance() : byzcoin_; + } + + public static final int X509CERT_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.GrantX509Cert x509Cert_; + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getX509Cert() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance() : x509Cert_; + } + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder getX509CertOrBuilder() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance() : x509Cert_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasX509Cert()) { + if (!getX509Cert().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getX509Cert()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getX509Cert()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Grant)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.Grant other = (ch.epfl.dedis.lib.proto.OCS.Grant) obj; + + if (hasByzcoin() != other.hasByzcoin()) return false; + if (hasByzcoin()) { + if (!getByzcoin() + .equals(other.getByzcoin())) return false; + } + if (hasX509Cert() != other.hasX509Cert()) return false; + if (hasX509Cert()) { + if (!getX509Cert() + .equals(other.getX509Cert())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasByzcoin()) { + hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; + hash = (53 * hash) + getByzcoin().hashCode(); + } + if (hasX509Cert()) { + hash = (37 * hash) + X509CERT_FIELD_NUMBER; + hash = (53 * hash) + getX509Cert().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Grant parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Grant parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Grant prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Grant holds one of the possible grant proofs for a reencryption request. Each
+     * grant proof must hold the secret to be reencrypted, the ephemeral key, as well
+     * as the proof itself that the request is valid. For each of the authentication
+     * schemes, this proof will be different.
+     * 
+ * + * Protobuf type {@code ocs.Grant} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.Grant) + ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Grant_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Grant_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Grant.class, ch.epfl.dedis.lib.proto.OCS.Grant.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.Grant.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getByzcoinFieldBuilder(); + getX509CertFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (x509CertBuilder_ == null) { + x509Cert_ = null; + } else { + x509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Grant_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Grant getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Grant build() { + ch.epfl.dedis.lib.proto.OCS.Grant result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Grant buildPartial() { + ch.epfl.dedis.lib.proto.OCS.Grant result = new ch.epfl.dedis.lib.proto.OCS.Grant(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + if (byzcoinBuilder_ == null) { + result.byzcoin_ = byzcoin_; + } else { + result.byzcoin_ = byzcoinBuilder_.build(); + } + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + if (x509CertBuilder_ == null) { + result.x509Cert_ = x509Cert_; + } else { + result.x509Cert_ = x509CertBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.Grant) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Grant)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Grant other) { + if (other == ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance()) return this; + if (other.hasByzcoin()) { + mergeByzcoin(other.getByzcoin()); + } + if (other.hasX509Cert()) { + mergeX509Cert(other.getX509Cert()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + return false; + } + } + if (hasX509Cert()) { + if (!getX509Cert().isInitialized()) { + return false; + } + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.Grant parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Grant) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private ch.epfl.dedis.lib.proto.OCS.GrantByzCoin byzcoin_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin, ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder> byzcoinBuilder_; + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getByzcoin() { + if (byzcoinBuilder_ == null) { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance() : byzcoin_; + } else { + return byzcoinBuilder_.getMessage(); + } + } + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin value) { + if (byzcoinBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + byzcoin_ = value; + onChanged(); + } else { + byzcoinBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + public Builder setByzcoin( + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder builderForValue) { + if (byzcoinBuilder_ == null) { + byzcoin_ = builderForValue.build(); + onChanged(); + } else { + byzcoinBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin value) { + if (byzcoinBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + byzcoin_ != null && + byzcoin_ != ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance()) { + byzcoin_ = + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); + } else { + byzcoin_ = value; + } + onChanged(); + } else { + byzcoinBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + public Builder clearByzcoin() { + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + onChanged(); + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder getByzcoinBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getByzcoinFieldBuilder().getBuilder(); + } + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder getByzcoinOrBuilder() { + if (byzcoinBuilder_ != null) { + return byzcoinBuilder_.getMessageOrBuilder(); + } else { + return byzcoin_ == null ? + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance() : byzcoin_; + } + } + /** + * optional .ocs.GrantByzCoin byzcoin = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin, ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder> + getByzcoinFieldBuilder() { + if (byzcoinBuilder_ == null) { + byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin, ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder>( + getByzcoin(), + getParentForChildren(), + isClean()); + byzcoin_ = null; + } + return byzcoinBuilder_; + } + + private ch.epfl.dedis.lib.proto.OCS.GrantX509Cert x509Cert_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert, ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder> x509CertBuilder_; + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getX509Cert() { + if (x509CertBuilder_ == null) { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance() : x509Cert_; + } else { + return x509CertBuilder_.getMessage(); + } + } + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + public Builder setX509Cert(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert value) { + if (x509CertBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + x509Cert_ = value; + onChanged(); + } else { + x509CertBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + public Builder setX509Cert( + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder builderForValue) { + if (x509CertBuilder_ == null) { + x509Cert_ = builderForValue.build(); + onChanged(); + } else { + x509CertBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert value) { + if (x509CertBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + x509Cert_ != null && + x509Cert_ != ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance()) { + x509Cert_ = + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); + } else { + x509Cert_ = value; + } + onChanged(); + } else { + x509CertBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + public Builder clearX509Cert() { + if (x509CertBuilder_ == null) { + x509Cert_ = null; + onChanged(); + } else { + x509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder getX509CertBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getX509CertFieldBuilder().getBuilder(); + } + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder getX509CertOrBuilder() { + if (x509CertBuilder_ != null) { + return x509CertBuilder_.getMessageOrBuilder(); + } else { + return x509Cert_ == null ? + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance() : x509Cert_; + } + } + /** + * optional .ocs.GrantX509Cert x509cert = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert, ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder> + getX509CertFieldBuilder() { + if (x509CertBuilder_ == null) { + x509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert, ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder>( + getX509Cert(), + getParentForChildren(), + isClean()); + x509Cert_ = null; + } + return x509CertBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.Grant) + } + + // @@protoc_insertion_point(class_scope:ocs.Grant) + private static final ch.epfl.dedis.lib.proto.OCS.Grant DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Grant(); + } + + public static ch.epfl.dedis.lib.proto.OCS.Grant getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Grant parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Grant(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Grant getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface GrantByzCoinOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.GrantByzCoin) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; + */ + boolean hasWrite(); + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; + */ + com.google.protobuf.ByteString getWrite(); + + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; + */ + boolean hasRead(); + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; + */ + com.google.protobuf.ByteString getRead(); + } + /** + *
+   * GrantByzCoin holds the proof of the write instance, holding the secret itself.
+   * The proof of the read instance holds the ephemeral key. Both proofs can be
+   * verified using one of the stored ByzCoinIDs.
+   * 
+ * + * Protobuf type {@code ocs.GrantByzCoin} + */ + public static final class GrantByzCoin extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.GrantByzCoin) + GrantByzCoinOrBuilder { + private static final long serialVersionUID = 0L; + // Use GrantByzCoin.newBuilder() to construct. + private GrantByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private GrantByzCoin() { + write_ = com.google.protobuf.ByteString.EMPTY; + read_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private GrantByzCoin( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + write_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + read_ = input.readBytes(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.class, ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder.class); + } + + private int bitField0_; + public static final int WRITE_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString write_; + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; + */ + public boolean hasWrite() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; + */ + public com.google.protobuf.ByteString getWrite() { + return write_; + } + + public static final int READ_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString read_; + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; + */ + public boolean hasRead() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; + */ + public com.google.protobuf.ByteString getRead() { + return read_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasWrite()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasRead()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, write_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeBytes(2, read_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, write_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, read_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.GrantByzCoin)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin other = (ch.epfl.dedis.lib.proto.OCS.GrantByzCoin) obj; + + if (hasWrite() != other.hasWrite()) return false; + if (hasWrite()) { + if (!getWrite() + .equals(other.getWrite())) return false; + } + if (hasRead() != other.hasRead()) return false; + if (hasRead()) { + if (!getRead() + .equals(other.getRead())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasWrite()) { + hash = (37 * hash) + WRITE_FIELD_NUMBER; + hash = (53 * hash) + getWrite().hashCode(); + } + if (hasRead()) { + hash = (37 * hash) + READ_FIELD_NUMBER; + hash = (53 * hash) + getRead().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * GrantByzCoin holds the proof of the write instance, holding the secret itself.
+     * The proof of the read instance holds the ephemeral key. Both proofs can be
+     * verified using one of the stored ByzCoinIDs.
+     * 
+ * + * Protobuf type {@code ocs.GrantByzCoin} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.GrantByzCoin) + ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.class, ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + write_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + read_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantByzCoin_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin build() { + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin buildPartial() { + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin result = new ch.epfl.dedis.lib.proto.OCS.GrantByzCoin(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.write_ = write_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.read_ = read_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.GrantByzCoin) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.GrantByzCoin)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin other) { + if (other == ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance()) return this; + if (other.hasWrite()) { + setWrite(other.getWrite()); + } + if (other.hasRead()) { + setRead(other.getRead()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasWrite()) { + return false; + } + if (!hasRead()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.GrantByzCoin) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString write_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; + */ + public boolean hasWrite() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; + */ + public com.google.protobuf.ByteString getWrite() { + return write_; + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; + */ + public Builder setWrite(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + write_ = value; + onChanged(); + return this; + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; + */ + public Builder clearWrite() { + bitField0_ = (bitField0_ & ~0x00000001); + write_ = getDefaultInstance().getWrite(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString read_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; + */ + public boolean hasRead() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; + */ + public com.google.protobuf.ByteString getRead() { + return read_; + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; + */ + public Builder setRead(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + read_ = value; + onChanged(); + return this; + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; + */ + public Builder clearRead() { + bitField0_ = (bitField0_ & ~0x00000002); + read_ = getDefaultInstance().getRead(); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.GrantByzCoin) + } + + // @@protoc_insertion_point(class_scope:ocs.GrantByzCoin) + private static final ch.epfl.dedis.lib.proto.OCS.GrantByzCoin DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.GrantByzCoin(); + } + + public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public GrantByzCoin parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new GrantByzCoin(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface GrantX509CertOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.GrantX509Cert) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes secret = 1; + */ + boolean hasSecret(); + /** + * required bytes secret = 1; + */ + com.google.protobuf.ByteString getSecret(); + + /** + * repeated bytes certificates = 2; + */ + java.util.List getCertificatesList(); + /** + * repeated bytes certificates = 2; + */ + int getCertificatesCount(); + /** + * repeated bytes certificates = 2; + */ + com.google.protobuf.ByteString getCertificates(int index); + } + /** + *
+   * GrantX509Cert holds the proof that at least a threshold number of clients
+   * accepted the reencryption.
+   * For each client, there must exist a certificate that can be verified by the
+   * CA certificate from AuthX509Cert. Additionally, each client must sign the
+   * following message:
+   *   sha256( Secret | Ephemeral | Time )
+   * 
+ * + * Protobuf type {@code ocs.GrantX509Cert} + */ + public static final class GrantX509Cert extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.GrantX509Cert) + GrantX509CertOrBuilder { + private static final long serialVersionUID = 0L; + // Use GrantX509Cert.newBuilder() to construct. + private GrantX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private GrantX509Cert() { + secret_ = com.google.protobuf.ByteString.EMPTY; + certificates_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private GrantX509Cert( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + secret_ = input.readBytes(); + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) != 0)) { + certificates_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + certificates_.add(input.readBytes()); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); // C + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantX509Cert_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.class, ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder.class); + } + + private int bitField0_; + public static final int SECRET_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString secret_; + /** + * required bytes secret = 1; + */ + public boolean hasSecret() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes secret = 1; + */ + public com.google.protobuf.ByteString getSecret() { + return secret_; + } + + public static final int CERTIFICATES_FIELD_NUMBER = 2; + private java.util.List certificates_; + /** + * repeated bytes certificates = 2; + */ + public java.util.List + getCertificatesList() { + return certificates_; + } + /** + * repeated bytes certificates = 2; + */ + public int getCertificatesCount() { + return certificates_.size(); + } + /** + * repeated bytes certificates = 2; + */ + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasSecret()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, secret_); + } + for (int i = 0; i < certificates_.size(); i++) { + output.writeBytes(2, certificates_.get(i)); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, secret_); + } + { + int dataSize = 0; + for (int i = 0; i < certificates_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(certificates_.get(i)); + } + size += dataSize; + size += 1 * getCertificatesList().size(); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.GrantX509Cert)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert other = (ch.epfl.dedis.lib.proto.OCS.GrantX509Cert) obj; + + if (hasSecret() != other.hasSecret()) return false; + if (hasSecret()) { + if (!getSecret() + .equals(other.getSecret())) return false; + } + if (!getCertificatesList() + .equals(other.getCertificatesList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasSecret()) { + hash = (37 * hash) + SECRET_FIELD_NUMBER; + hash = (53 * hash) + getSecret().hashCode(); + } + if (getCertificatesCount() > 0) { + hash = (37 * hash) + CERTIFICATES_FIELD_NUMBER; + hash = (53 * hash) + getCertificatesList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * GrantX509Cert holds the proof that at least a threshold number of clients
+     * accepted the reencryption.
+     * For each client, there must exist a certificate that can be verified by the
+     * CA certificate from AuthX509Cert. Additionally, each client must sign the
+     * following message:
+     *   sha256( Secret | Ephemeral | Time )
+     * 
+ * + * Protobuf type {@code ocs.GrantX509Cert} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.GrantX509Cert) + ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantX509Cert_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.class, ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + secret_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + certificates_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantX509Cert_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert build() { + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert buildPartial() { + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert result = new ch.epfl.dedis.lib.proto.OCS.GrantX509Cert(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.secret_ = secret_; + if (((bitField0_ & 0x00000002) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.certificates_ = certificates_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.GrantX509Cert) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.GrantX509Cert)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert other) { + if (other == ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance()) return this; + if (other.hasSecret()) { + setSecret(other.getSecret()); + } + if (!other.certificates_.isEmpty()) { + if (certificates_.isEmpty()) { + certificates_ = other.certificates_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureCertificatesIsMutable(); + certificates_.addAll(other.certificates_); + } + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasSecret()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.GrantX509Cert) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString secret_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes secret = 1; + */ + public boolean hasSecret() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes secret = 1; + */ + public com.google.protobuf.ByteString getSecret() { + return secret_; + } + /** + * required bytes secret = 1; + */ + public Builder setSecret(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + secret_ = value; + onChanged(); + return this; + } + /** + * required bytes secret = 1; + */ + public Builder clearSecret() { + bitField0_ = (bitField0_ & ~0x00000001); + secret_ = getDefaultInstance().getSecret(); + onChanged(); + return this; + } + + private java.util.List certificates_ = java.util.Collections.emptyList(); + private void ensureCertificatesIsMutable() { + if (!((bitField0_ & 0x00000002) != 0)) { + certificates_ = new java.util.ArrayList(certificates_); + bitField0_ |= 0x00000002; + } + } + /** + * repeated bytes certificates = 2; + */ + public java.util.List + getCertificatesList() { + return ((bitField0_ & 0x00000002) != 0) ? + java.util.Collections.unmodifiableList(certificates_) : certificates_; + } + /** + * repeated bytes certificates = 2; + */ + public int getCertificatesCount() { + return certificates_.size(); + } + /** + * repeated bytes certificates = 2; + */ + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); + } + /** + * repeated bytes certificates = 2; + */ + public Builder setCertificates( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCertificatesIsMutable(); + certificates_.set(index, value); + onChanged(); + return this; + } + /** + * repeated bytes certificates = 2; + */ + public Builder addCertificates(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCertificatesIsMutable(); + certificates_.add(value); + onChanged(); + return this; + } + /** + * repeated bytes certificates = 2; + */ + public Builder addAllCertificates( + java.lang.Iterable values) { + ensureCertificatesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, certificates_); + onChanged(); + return this; + } + /** + * repeated bytes certificates = 2; + */ + public Builder clearCertificates() { + certificates_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.GrantX509Cert) + } + + // @@protoc_insertion_point(class_scope:ocs.GrantX509Cert) + private static final ch.epfl.dedis.lib.proto.OCS.GrantX509Cert DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.GrantX509Cert(); + } + + public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public GrantX509Cert parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new GrantX509Cert(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_CreateOCS_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_CreateOCS_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_CreateOCSReply_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_CreateOCSReply_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_Reencrypt_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_Reencrypt_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_ReencryptReply_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_ReencryptReply_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_Auth_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_Auth_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AuthByzCoin_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AuthByzCoin_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AuthX509Cert_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AuthX509Cert_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_Grant_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_Grant_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_GrantByzCoin_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_GrantByzCoin_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_GrantX509Cert_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_GrantX509Cert_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\tocs.proto\022\003ocs\032\nonet.proto\"L\n\tCreateOC" + + "S\022\034\n\006roster\030\001 \002(\0132\014.onet.Roster\022!\n\016authe" + + "ntication\030\002 \002(\0132\t.ocs.Auth\"(\n\016CreateOCSR" + + "eply\022\t\n\001x\030\001 \002(\014\022\013\n\003sig\030\002 \002(\014\"1\n\tReencryp" + + "t\022\t\n\001x\030\001 \002(\014\022\031\n\005grant\030\002 \002(\0132\n.ocs.Grant\"" + + "\036\n\016ReencryptReply\022\014\n\004xhat\030\001 \002(\014\"R\n\004Auth\022" + + "!\n\007byzcoin\030\001 \001(\0132\020.ocs.AuthByzCoin\022\'\n\014au" + + "thx509cert\030\002 \001(\0132\021.ocs.AuthX509Cert\"-\n\013A" + + "uthByzCoin\022\021\n\tbyzcoinid\030\001 \002(\014\022\013\n\003ttl\030\002 \002" + + "(\004\"-\n\014AuthX509Cert\022\n\n\002ca\030\001 \003(\014\022\021\n\tthresh" + + "old\030\002 \002(\021\"Q\n\005Grant\022\"\n\007byzcoin\030\001 \001(\0132\021.oc" + + "s.GrantByzCoin\022$\n\010x509cert\030\002 \001(\0132\022.ocs.G" + + "rantX509Cert\"+\n\014GrantByzCoin\022\r\n\005write\030\001 " + + "\002(\014\022\014\n\004read\030\002 \002(\014\"5\n\rGrantX509Cert\022\016\n\006se" + + "cret\030\001 \002(\014\022\024\n\014certificates\030\002 \003(\014B\036\n\027ch.e" + + "pfl.dedis.lib.protoB\003OCS" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + ch.epfl.dedis.lib.proto.OnetProto.getDescriptor(), + }, assigner); + internal_static_ocs_CreateOCS_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_ocs_CreateOCS_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_CreateOCS_descriptor, + new java.lang.String[] { "Roster", "Authentication", }); + internal_static_ocs_CreateOCSReply_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_ocs_CreateOCSReply_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_CreateOCSReply_descriptor, + new java.lang.String[] { "X", "Sig", }); + internal_static_ocs_Reencrypt_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_ocs_Reencrypt_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_Reencrypt_descriptor, + new java.lang.String[] { "X", "Grant", }); + internal_static_ocs_ReencryptReply_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_ocs_ReencryptReply_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_ReencryptReply_descriptor, + new java.lang.String[] { "Xhat", }); + internal_static_ocs_Auth_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_ocs_Auth_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_Auth_descriptor, + new java.lang.String[] { "Byzcoin", "Authx509Cert", }); + internal_static_ocs_AuthByzCoin_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_ocs_AuthByzCoin_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AuthByzCoin_descriptor, + new java.lang.String[] { "Byzcoinid", "Ttl", }); + internal_static_ocs_AuthX509Cert_descriptor = + getDescriptor().getMessageTypes().get(6); + internal_static_ocs_AuthX509Cert_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AuthX509Cert_descriptor, + new java.lang.String[] { "Ca", "Threshold", }); + internal_static_ocs_Grant_descriptor = + getDescriptor().getMessageTypes().get(7); + internal_static_ocs_Grant_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_Grant_descriptor, + new java.lang.String[] { "Byzcoin", "X509Cert", }); + internal_static_ocs_GrantByzCoin_descriptor = + getDescriptor().getMessageTypes().get(8); + internal_static_ocs_GrantByzCoin_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_GrantByzCoin_descriptor, + new java.lang.String[] { "Write", "Read", }); + internal_static_ocs_GrantX509Cert_descriptor = + getDescriptor().getMessageTypes().get(9); + internal_static_ocs_GrantX509Cert_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_GrantX509Cert_descriptor, + new java.lang.String[] { "Secret", "Certificates", }); + ch.epfl.dedis.lib.proto.OnetProto.getDescriptor(); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/external/proto/calypso.proto b/external/proto/calypso.proto index 144f5ac6f8..bfe987dcbb 100644 --- a/external/proto/calypso.proto +++ b/external/proto/calypso.proto @@ -116,64 +116,3 @@ message GetLTSReply { message LtsInstanceInfo { required onet.Roster roster = 1; } - -// -// V4 proposed extensions -// - -// Auth holds all possible authentication structures. When using it to call -// Authorise, only one of the fields must be non-nil. -message Auth { - optional AuthByzCoin byzcoin = 1; - optional AuthX509Cert authx509cert = 2; -} - -// AuthByzCoin holds the information necessary to authenticate a byzcoin request. -// In the ByzCoin model, all requests are valid as long as they are stored in the -// blockchain with the given ID. -// The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled. -message AuthByzCoin { - required bytes byzcoinid = 1; - required uint64 ttl = 2; -} - -// AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric -// request. In its simplest form, it is simply the CA that will have to sign the -// certificates of the requesters. -// The Threshold indicates how many clients must have signed the request before it -// is accepted. -message AuthX509Cert { - // Slice of ASN.1 encoded X509 certificates. - repeated bytes ca = 1; - required sint32 threshold = 2; -} - -// Grant holds one of the possible grant proofs for a reencryption request. Each -// grant proof must hold the secret to be reencrypted, the ephemeral key, as well -// as the proof itself that the request is valid. For each of the authentication -// schemes, this proof will be different. -message Grant { - optional GrantByzCoin byzcoin = 1; - optional GrantX509Cert x509cert = 2; -} - -// GrantByzCoin holds the proof of the write instance, holding the secret itself. -// The proof of the read instance holds the ephemeral key. Both proofs can be -// verified using one of the stored ByzCoinIDs. -message GrantByzCoin { - // Write is the proof containing the write request. - required byzcoin.Proof write = 1; - // Read is the proof that he has been accepted to read the secret. - required byzcoin.Proof read = 2; -} - -// GrantX509Cert holds the proof that at least a threshold number of clients -// accepted the reencryption. -// For each client, there must exist a certificate that can be verified by the -// CA certificate from AuthX509Cert. Additionally, each client must sign the -// following message: -// sha256( Secret | Ephemeral | Time ) -message GrantX509Cert { - required bytes secret = 1; - repeated bytes certificates = 2; -} diff --git a/external/proto/ocs.proto b/external/proto/ocs.proto new file mode 100644 index 0000000000..3435935a0a --- /dev/null +++ b/external/proto/ocs.proto @@ -0,0 +1,103 @@ +syntax = "proto2"; +package ocs; +import "onet.proto"; + +option java_package = "ch.epfl.dedis.lib.proto"; +option java_outer_classname = "OCS"; + +// *** +// API calls +// *** + +// CreateOCS is sent to the service to request a new OCS cothority. +message CreateOCS { + required onet.Roster roster = 1; + required Auth authentication = 2; +} + +// CreateOCSReply is the reply sent by the conode if the OCS has been +// setup correctly. It contains the ID of the OCS, which is the binary +// representation of the aggregate public key. It also has the Sig, which +// is the collective signature of all nodes on the aggregate public key +// and the authentication. +message CreateOCSReply { + required bytes x = 1; + required bytes sig = 2; +} + +// Reencrypt is sent to the service to request a re-encryption of the +// secret given in Grant. Grant must also contain the proof that the +// request is valid, as well as the ephemeral key, to which the secret +// will be re-encrypted. +message Reencrypt { + required bytes x = 1; + required Grant grant = 2; +} + +// ReencryptReply is the reply if the re-encryption is successful, and +// it contains XHat, which is the secret re-encrypted to the ephemeral +// key given in Grant. +message ReencryptReply { + required bytes xhat = 1; +} + +// *** +// Common structures +// *** + +// Auth holds all possible authentication structures. When using it to call +// Authorise, only one of the fields must be non-nil. +message Auth { + optional AuthByzCoin byzcoin = 1; + optional AuthX509Cert authx509cert = 2; +} + +// AuthByzCoin holds the information necessary to authenticate a byzcoin request. +// In the ByzCoin model, all requests are valid as long as they are stored in the +// blockchain with the given ID. +// The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled. +message AuthByzCoin { + required bytes byzcoinid = 1; + required uint64 ttl = 2; +} + +// AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric +// request. In its simplest form, it is simply the CA that will have to sign the +// certificates of the requesters. +// The Threshold indicates how many clients must have signed the request before it +// is accepted. +message AuthX509Cert { + // Slice of ASN.1 encoded X509 certificates. + repeated bytes ca = 1; + required sint32 threshold = 2; +} + +// Grant holds one of the possible grant proofs for a reencryption request. Each +// grant proof must hold the secret to be reencrypted, the ephemeral key, as well +// as the proof itself that the request is valid. For each of the authentication +// schemes, this proof will be different. +message Grant { + optional GrantByzCoin byzcoin = 1; + optional GrantX509Cert x509cert = 2; +} + +// GrantByzCoin holds the proof of the write instance, holding the secret itself. +// The proof of the read instance holds the ephemeral key. Both proofs can be +// verified using one of the stored ByzCoinIDs. +message GrantByzCoin { + // Write is the proof containing the write request. + required bytes write = 1; + // Read is the proof that he has been accepted to read the secret. + required bytes read = 2; +} + +// GrantX509Cert holds the proof that at least a threshold number of clients +// accepted the reencryption. +// For each client, there must exist a certificate that can be verified by the +// CA certificate from AuthX509Cert. Additionally, each client must sign the +// following message: +// sha256( Secret | Ephemeral | Time ) +message GrantX509Cert { + required bytes secret = 1; + repeated bytes certificates = 2; +} diff --git a/ocs/OCS.md b/ocs/OCS.md new file mode 100644 index 0000000000..afbc9b1769 --- /dev/null +++ b/ocs/OCS.md @@ -0,0 +1,34 @@ +Navigation: [DEDIS](https://github.com/dedis/doc/tree/master/README.md) :: +[Cothority](../README.md) :: +[Applications](../doc/Applications.md) :: +[Onchain Secrets](README.md) :: +Protocols + +# Protocols + +The onet-framework uses protocols at its lowest level to define communication +patterns betwen nodes. We use two protocols in the onchain-secrets service: + +- [DKG](../dkg/DKG.md) - Distributed Key Generation, an implementation of + the following paper: "Secure Distributed Key Generation for Discrete-Log + Based Cryptosystems" by R. Gennaro, S. Jarecki, H. Krawczyk, and T. Rabin. +- [ocs](Renecrypt.md) - the long-term secrets version of the on-chain secrets + protocol with server-side secret reconstruction described in + [CALYPSO](https://eprint.iacr.org/2018/209.pdf). + +## Distributed Key Generation + +The DKG protocol creates random shares of a secret key that are only +stored at each node. Together these nodes create a public shared key +without creating the secret shared key. As a group they can encrypt +and decrypt data without the need to create the secret shared key, +but with each node participating in part of the encryption or +decryption. For more information, please see [here](../dkg/DKG.md). + +## Onchain-Secrets + +Based on the DKG, data that is ElGamal encrypted using the public +shared key from the DKG can be re-encrypted under another public key +without the data being in the clear at any given moment. This is used +in the onchain-secrets skipchain when a reader wants to recover the +symmetric key. diff --git a/ocs/README.md b/ocs/README.md new file mode 100644 index 0000000000..ae4e441a95 --- /dev/null +++ b/ocs/README.md @@ -0,0 +1,115 @@ +Navigation: [DEDIS](https://github.com/dedis/doc/tree/master/README.md) :: +[Cothority](../README.md) :: +[Applications](../doc/Applications.md) :: +Calypso + +# Calypso + +Calypso is the implementation of the upcoming "Calypso - Auditable Sharing of +Private Data over Blockchains". The paper can be found +[here](https://eprint.iacr.org/2018/209). + +In short, Calypso allows to store symmetric keys in ByzCoin, protected by a +sharded key, and controls access to this symmetric keys using Darcs, +Distributed Access Rights Control. + +It implements both the access-control cothority and the secret-management +cothority: +- The access-control cothority is implemented using ByzCoin with two + contracts, `calypsoWrite` and `calypsoRead` +- The secret-management cothority uses an onet service with methods to set up a + Long Term Secret (LTS) distributed key and to request a re-encryption + +The workflow is the following: +1. secret-management: Administrator sets up a new LTS for all his clients. It + does so by calling the `CreateLTS` service endpoint. The resulting `LTSID` + will be used by all clients. +2. access-control: Administrator gives document creation rights to a writer +3. access-control: Writer creates new Darcs for customers and for documents. +4. access-control: Writer spawns a `Write` instance from a document Darc +5. access-control: Reader requests that a `Read` instance is spawned from a + `Write` instance +6. secret-management: Reader requests a re-encryption to the `DecryptKey` + service endpoint. + +![Workflow Overview](CalypsoByzCoin.png?raw=true "Workflow Overview") + +## Darcs, Instances, Instructions and Contracts + +Here is a very short overview of the three most important elements of +ByzCoin. For a more thorough documentation, refer to +[ByzCoin](../byzcoin/README.md) documentation. + +The current ByzCoin service is a batching implementation of the previous +skipchain service. It has a global state that holds _Instances_, where every +instance is tied to a _Contract_ and holds a blob of data. The contract defines +how the data is to be interpreted and allows different _Instructions_ sent from +the user. + +Access control is done using _Darcs_, which define what public keys can verify +an action. Each instruction received by ByzCoin is mapped to an action and +then verified if the given signature is correct. Also, every instance is linked +to one darc that defines what actions are allowed to be done to that instance. + +All instructions sent to ByzCoin are batched in a new block that is created +every `blockInterval` seconds. + +## CreateLTS + +The CreateLTS endpoint is only usable when connecting to the conode +via localhost. It is possible to relax this restriction, but it should +only be done in testing environments; see `service.go`'s `init()` function +for how. + +The client that initiates `CreateLTS` should hold two rosters. One roster for +storing the secret shares of LTS (long term secret), the other for a ByzCoin +instance for storing the LTS roster (using the LTS contract). + +If the LTS roster does not exist on ByzCoin, the client is responsible for +creating it. Which can be done by sending a ByzCoin transaction. The +transaction should spawn a new LTS instance. + +After the LTS roster is on ByzCoin but before the creation of LTS shares. The +client should make a `CreateLTS` request to a node in the LTS roster. The +request should contain the instance ID that contains the LTS roster. Then, +every Calypso node should check that the instance ID that holds the LTS roster +exists before starting the DKG. For this operation, all nodes must be online. +By default, a threshold of 2/3 of the nodes must be present for the +decryption. + +The CreateLTS service endpoint returns a `LTSID` in the form of a 32 byte +slice. This ID represents the group that created the distributed key. Any node +can participate in as many DKGs as you want and will get a random `LTSID` +assigned. + +## Write Contract + +The write contract verifies that the request has been correctly created, so +that no malicious writer can send an encrypted key without knowing the secret. +It then creates a new write-instance that contains the write request. + +A read request must also be sent to the write contract, which will forward it +to the read contract. This is so that every instruction sent to ByzCoin has +as a target an existing instance. + +## Read Contract + +The read contract verifies that the request is valid and points to the write +instance. It stores the reader's public key in the instance, so that the +secret-management cothority can re-encrypt to this reader's public key. + +## Resharing LTS + +It is possible that the roster might change and the LTS shares must be +re-distributed but without changing the LTS itself. We accomplish this in two +steps. + +1. The authorised client(s) must update the LTS roster in the blockchain (an + instance of the LTS smart contract). +2. Then, the client instructs the calypso conodes to run the resharing + protocol. The nodes in the new roster find and check the proof of + roster-change in ByzCoin, and then start the protocol to reshare the secret + between themselves. + +For this operation, all nodes must be online. By default, a threshold of 2/3 of +the nodes must be present for the decryption. \ No newline at end of file diff --git a/ocs/Reencrypt.md b/ocs/Reencrypt.md new file mode 100644 index 0000000000..c6f4b26249 --- /dev/null +++ b/ocs/Reencrypt.md @@ -0,0 +1,32 @@ +Navigation: [DEDIS](https://github.com/dedis/doc/tree/master/README.md) :: +[Cothority](../README.md) :: +[Building Blocks](../doc/BuildingBlocks.md) :: +Distributed Reencryption + +# Distributed Reencryption + +Once a [DKG](../dkg/DKG.md) has been set up, its aggregated public key can +be used to encrypt data, for example using ElGamal encryption. In some +circumstances you don't want to directly decrypt that data, but merely give +access to another user, without the distributed setup seeing what the original +data is. + +We call this _re-encryption_, because it takes encrypted data and outputs +an encrypted blob that can be decrypted by another private key than the one +used in the DKG. This is done by having each node decrypting the data with +his share of the key, and then encrypting it to the new key. As each no only +has a share of the key, the original data is never revealed. However, the end +result is encrypted to a new public key and can be decrypted using the corresponding +private key. + +## Files + +The re-encryption protocol is called _ocs_ and is defined in the following files: +- [ocs.go](ocs.go) +- [ocs_struct.go](ocs_struct.go) +- [ocs_test.go](ocs_test.go) + +## Research Papers + +- [CALYPSO](https://eprint.iacr.org/2018/209.pdf) - Auditable Sharing of + Private Data over Blockchains diff --git a/ocs/api.go b/ocs/api.go new file mode 100644 index 0000000000..07bd1af141 --- /dev/null +++ b/ocs/api.go @@ -0,0 +1,64 @@ +package ocs + +import ( + "go.dedis.ch/cothority/v3" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/onet/v3" +) + +// TODO: add OCSID of type kyber.Point +// TODO: think about authentication +// TODO: add CreateAndAuthorise +// TODO: add REST interface + +type OCSID kyber.Point + +// ClientV4 is a class to communicate to the calypso service. +type ClientV4 struct { + *onet.Client +} + +// NewClientV4 creates a new client to interact with the Calypso Service. +func NewClientV4() *ClientV4 { + return &ClientV4{Client: onet.NewClient(cothority.Suite, ServiceName)} +} + +// CreateLTS starts a new Distributed Key Generation with the nodes in the roster and +// returns the collective public key X. This X is also used later to identify the +// LTS instance, as there can be more than one LTS group on a node. +// +// It also sets up an authorisation option for the nodes. +// +// This can only be called from localhost, except if the environment variable +// COTHORITY_ALLOW_INSECURE_ADMIN is set to 'true'. +// +// In case of error, X is nil, and the error indicates what is wrong. +// The `sig` returned is a collective signature on the following hash: +// sha256( X | protobuf.Encode(auth) ) +// It can be verified using the aggregate service key from the roster: +// msg := sha256.New() +// Xbuf, err := X.MarshalBinary() +// // Check for errors +// msg.Write(Xbuf) +// authBuf, err := protobuf.Encode(auth) +// // Check for errors +// err = schnorr.Verify(cothority.Suite, roster.ServiceAggregate(calypso.ServiceName), +// msg.Sum(nil), sig) +// // If err == nil, the signature is correct +func (c *ClientV4) CreateLTS(ltsRoster *onet.Roster, auth Auth) (X OCSID, sig []byte, err error) { + return +} + +// Reencrypt requests the re-encryption of the secret stored in the grant. +// The grant must also contain the ephemeral key to which the secret will be +// reencrypted to. +// Finally the grant must contain information about how to verify that the +// reencryption request is valid. +// +// This can be called from anywhere. +// +// If the grant is valid, the reencrypted XHat is returned and err is nil. In case +// of error, XHat is nil, and the error will be returned. +func (c *ClientV4) Reencrypt(X kyber.Point, grant Grant) (XHat kyber.Point, err error) { + return +} diff --git a/ocs/db.go b/ocs/db.go new file mode 100644 index 0000000000..a6f39eda1f --- /dev/null +++ b/ocs/db.go @@ -0,0 +1,93 @@ +package ocs + +import ( + "errors" + "sync" + + "go.dedis.ch/cothority/v3/byzcoin" + dkgprotocol "go.dedis.ch/cothority/v3/dkg/pedersen" + dkg "go.dedis.ch/kyber/v3/share/dkg/pedersen" + "go.dedis.ch/onet/v3" + "go.dedis.ch/onet/v3/log" +) + +const dbVersion = 1 + +// storageKey reflects the data we're storing - we could store more +// than one structure. +var storageKey = []byte("storage") + +// storage is used to save all elements of the DKG. +type storage struct { + AuthorisedByzCoinIDs map[string]bool + + Shared map[byzcoin.InstanceID]*dkgprotocol.SharedSecret + Polys map[byzcoin.InstanceID]*pubPoly + Rosters map[byzcoin.InstanceID]*onet.Roster + DKS map[byzcoin.InstanceID]*dkg.DistKeyShare + + sync.Mutex +} + +// saves all data. +func (s *Service) save() error { + s.storage.Lock() + defer s.storage.Unlock() + err := s.Save(storageKey, s.storage) + if err != nil { + log.Error("Couldn't save data:", err) + return err + } + return nil +} + +// Tries to load the configuration and updates the data in the service +// if it finds a valid config-file. +func (s *Service) tryLoad() error { + s.storage = &storage{} + ver, err := s.LoadVersion() + if err != nil { + return err + } + + // Make sure we don't have any unallocated maps. + defer func() { + if len(s.storage.Polys) == 0 { + s.storage.Polys = make(map[byzcoin.InstanceID]*pubPoly) + } + if len(s.storage.Shared) == 0 { + s.storage.Shared = make(map[byzcoin.InstanceID]*dkgprotocol.SharedSecret) + } + if len(s.storage.Rosters) == 0 { + s.storage.Rosters = make(map[byzcoin.InstanceID]*onet.Roster) + } + if len(s.storage.DKS) == 0 { + s.storage.DKS = make(map[byzcoin.InstanceID]*dkg.DistKeyShare) + } + if len(s.storage.AuthorisedByzCoinIDs) == 0 { + s.storage.AuthorisedByzCoinIDs = make(map[string]bool) + } + }() + + // In the future, we'll make database upgrades below. + if ver < dbVersion { + // There is no version 0. Save empty storage and update version number. + if err = s.save(); err != nil { + return err + } + return s.SaveVersion(dbVersion) + } + msg, err := s.Load(storageKey) + if err != nil { + return err + } + if msg == nil { + return nil + } + var ok bool + s.storage, ok = msg.(*storage) + if !ok { + return errors.New("data of wrong type") + } + return nil +} diff --git a/calypso/api_v4.go b/ocs/proto.go similarity index 51% rename from calypso/api_v4.go rename to ocs/proto.go index 0681786b11..2a949ae7f3 100644 --- a/calypso/api_v4.go +++ b/ocs/proto.go @@ -1,75 +1,64 @@ -package calypso +package ocs import ( "time" - "go.dedis.ch/cothority/v3" "go.dedis.ch/cothority/v3/byzcoin" "go.dedis.ch/cothority/v3/skipchain" "go.dedis.ch/kyber/v3" "go.dedis.ch/onet/v3" ) -// TODO: add LTSID of type kyber.Point -// TODO: think about authentication -// TODO: add CreateAndAuthorise -// TODO: add REST interface +// PROTOSTART +// type :skipchain.SkipBlockID:bytes +// type :time.Time:uint64 +// type :byzcoin.Proof:bytes +// type :OCSID:bytes +// package ocs; +// import "onet.proto"; +// +// option java_package = "ch.epfl.dedis.lib.proto"; +// option java_outer_classname = "OCS"; -type LTSID kyber.Point +// *** +// API calls +// *** -// ClientV4 is a class to communicate to the calypso service. -type ClientV4 struct { - *onet.Client +// CreateOCS is sent to the service to request a new OCS cothority. +type CreateOCS struct { + Roster onet.Roster + Authentication Auth } -// NewClientV4 creates a new client to interact with the Calypso Service. -func NewClientV4() *ClientV4 { - return &ClientV4{Client: onet.NewClient(cothority.Suite, ServiceName)} +// CreateOCSReply is the reply sent by the conode if the OCS has been +// setup correctly. It contains the ID of the OCS, which is the binary +// representation of the aggregate public key. It also has the Sig, which +// is the collective signature of all nodes on the aggregate public key +// and the authentication. +type CreateOCSReply struct { + X OCSID + Sig []byte } -// CreateLTS starts a new Distributed Key Generation with the nodes in the roster and -// returns the collective public key X. This X is also used later to identify the -// LTS instance, as there can be more than one LTS group on a node. -// -// It also sets up an authorisation option for the nodes. -// -// This can only be called from localhost, except if the environment variable -// COTHORITY_ALLOW_INSECURE_ADMIN is set to 'true'. -// -// In case of error, X is nil, and the error indicates what is wrong. -// The `sig` returned is a collective signature on the following hash: -// sha256( X | protobuf.Encode(auth) ) -// It can be verified using the aggregate service key from the roster: -// msg := sha256.New() -// Xbuf, err := X.MarshalBinary() -// // Check for errors -// msg.Write(Xbuf) -// authBuf, err := protobuf.Encode(auth) -// // Check for errors -// err = schnorr.Verify(cothority.Suite, roster.ServiceAggregate(calypso.ServiceName), -// msg.Sum(nil), sig) -// // If err == nil, the signature is correct -func (c *ClientV4) CreateLTS(ltsRoster *onet.Roster, auth Auth) (X LTSID, sig []byte, err error) { - return +// Reencrypt is sent to the service to request a re-encryption of the +// secret given in Grant. Grant must also contain the proof that the +// request is valid, as well as the ephemeral key, to which the secret +// will be re-encrypted. +type Reencrypt struct { + X OCSID + Grant Grant } -// Reencrypt requests the re-encryption of the secret stored in the grant. -// The grant must also contain the ephemeral key to which the secret will be -// reencrypted to. -// Finally the grant must contain information about how to verify that the -// reencryption request is valid. -// -// This can be called from anywhere. -// -// If the grant is valid, the reencrypted XHat is returned and err is nil. In case -// of error, XHat is nil, and the error will be returned. -func (c *ClientV4) Reencrypt(X kyber.Point, grant Grant) (XHat kyber.Point, err error) { - return +// ReencryptReply is the reply if the re-encryption is successful, and +// it contains XHat, which is the secret re-encrypted to the ephemeral +// key given in Grant. +type ReencryptReply struct { + XHat kyber.Point } -// -// V4 proposed extensions -// +// *** +// Common structures +// *** // Auth holds all possible authentication structures. When using it to call // Authorise, only one of the fields must be non-nil. diff --git a/ocs/protocol.go b/ocs/protocol.go new file mode 100644 index 0000000000..c3f0780f4e --- /dev/null +++ b/ocs/protocol.go @@ -0,0 +1,214 @@ +package ocs + +/* +The onchain-protocol implements the key-reencryption described in Lefteris' +paper-draft about onchain-secrets (called BlockMage). +*/ + +import ( + "crypto/sha256" + "errors" + "sync" + "time" + + "go.dedis.ch/cothority/v3" + dkgprotocol "go.dedis.ch/cothority/v3/dkg/pedersen" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/share" + "go.dedis.ch/onet/v3" + "go.dedis.ch/onet/v3/log" +) + +func init() { + onet.GlobalProtocolRegister(NameOCS, NewOCS) +} + +// OCS is only used to re-encrypt a public point. Before calling `Start`, +// DKG and U must be initialized by the caller. +type OCS struct { + *onet.TreeNodeInstance + Shared *dkgprotocol.SharedSecret // Shared represents the private key + Poly *share.PubPoly // Represents all public keys + U kyber.Point // U is the encrypted secret + Xc kyber.Point // The client's public key + Threshold int // How many replies are needed to re-create the secret + // VerificationData is given to the VerifyRequest and has to hold everything + // needed to verify the request is valid. + VerificationData []byte + Failures int // How many failures occured so far + // Can be set by the service to decide whether or not to + // do the reencryption + Verify VerifyRequest + // Reencrypted receives a 'true'-value when the protocol finished successfully, + // or 'false' if not enough shares have been collected. + Reencrypted chan bool + Uis []*share.PubShare // re-encrypted shares + // private fields + replies []ReencryptReply + timeout *time.Timer + doneOnce sync.Once +} + +// NewOCS initialises the structure for use in one round +func NewOCS(n *onet.TreeNodeInstance) (onet.ProtocolInstance, error) { + o := &OCS{ + TreeNodeInstance: n, + Reencrypted: make(chan bool, 1), + Threshold: len(n.Roster().List) - (len(n.Roster().List)-1)/3, + } + + err := o.RegisterHandlers(o.reencrypt, o.reencryptReply) + if err != nil { + return nil, err + } + return o, nil +} + +// Start asks all children to reply with a shared reencryption +func (o *OCS) Start() error { + log.Lvl3("Starting Protocol") + if o.Shared == nil { + o.finish(false) + return errors.New("please initialize Shared first") + } + if o.U == nil { + o.finish(false) + return errors.New("please initialize U first") + } + rc := &Reencrypt{ + U: o.U, + Xc: o.Xc, + } + if len(o.VerificationData) > 0 { + rc.VerificationData = &o.VerificationData + } + if o.Verify != nil { + if !o.Verify(rc) { + o.finish(false) + return errors.New("refused to reencrypt") + } + } + o.timeout = time.AfterFunc(1*time.Minute, func() { + log.Lvl1("OCS protocol timeout") + o.finish(false) + }) + errs := o.Broadcast(rc) + if len(errs) > (len(o.Roster().List)-1)/3 { + log.Errorf("Some nodes failed with error(s) %v", errs) + return errors.New("too many nodes failed in broadcast") + } + return nil +} + +// Reencrypt is received by every node to give his part of +// the share +func (o *OCS) reencrypt(r structReencrypt) error { + log.Lvl3(o.Name() + ": starting reencrypt") + defer o.Done() + + ui, err := o.getUI(r.U, r.Xc) + if err != nil { + return nil + } + + if o.Verify != nil { + if !o.Verify(&r.Reencrypt) { + log.Lvl2(o.ServerIdentity(), "refused to reencrypt") + return o.SendToParent(&ReencryptReply{}) + } + } + + // Calculating proofs + si := cothority.Suite.Scalar().Pick(o.Suite().RandomStream()) + uiHat := cothority.Suite.Point().Mul(si, cothority.Suite.Point().Add(r.U, r.Xc)) + hiHat := cothority.Suite.Point().Mul(si, nil) + hash := sha256.New() + ui.V.MarshalTo(hash) + uiHat.MarshalTo(hash) + hiHat.MarshalTo(hash) + ei := cothority.Suite.Scalar().SetBytes(hash.Sum(nil)) + + return o.SendToParent(&ReencryptReply{ + Ui: ui, + Ei: ei, + Fi: cothority.Suite.Scalar().Add(si, cothority.Suite.Scalar().Mul(ei, o.Shared.V)), + }) +} + +// reencryptReply is the root-node waiting for all replies and generating +// the reencryption key. +func (o *OCS) reencryptReply(rr structReencryptReply) error { + if rr.ReencryptReply.Ui == nil { + log.Lvl2("Node", rr.ServerIdentity, "refused to reply") + o.Failures++ + if o.Failures > len(o.Roster().List)-o.Threshold { + log.Lvl2(rr.ServerIdentity, "couldn't get enough shares") + o.finish(false) + } + return nil + } + o.replies = append(o.replies, rr.ReencryptReply) + + // minus one to exclude the root + if len(o.replies) >= int(o.Threshold-1) { + o.Uis = make([]*share.PubShare, len(o.List())) + var err error + o.Uis[0], err = o.getUI(o.U, o.Xc) + if err != nil { + return err + } + + for _, r := range o.replies { + // Verify proofs + ufi := cothority.Suite.Point().Mul(r.Fi, cothority.Suite.Point().Add(o.U, o.Xc)) + uiei := cothority.Suite.Point().Mul(cothority.Suite.Scalar().Neg(r.Ei), r.Ui.V) + uiHat := cothority.Suite.Point().Add(ufi, uiei) + + gfi := cothority.Suite.Point().Mul(r.Fi, nil) + gxi := o.Poly.Eval(r.Ui.I).V + hiei := cothority.Suite.Point().Mul(cothority.Suite.Scalar().Neg(r.Ei), gxi) + hiHat := cothority.Suite.Point().Add(gfi, hiei) + hash := sha256.New() + r.Ui.V.MarshalTo(hash) + uiHat.MarshalTo(hash) + hiHat.MarshalTo(hash) + e := cothority.Suite.Scalar().SetBytes(hash.Sum(nil)) + if e.Equal(r.Ei) { + o.Uis[r.Ui.I] = r.Ui + } else { + log.Lvl1("Received invalid share from node", r.Ui.I) + } + } + o.finish(true) + } + + // If we are leaving by here it means that we do not have + // enough replies yet. We must eventually trigger a finish() + // somehow. It will either happen because we get another + // reply, and now we have enough, or because we get enough + // failures and know to give up, or because o.timeout triggers + // and calls finish(false) in it's callback function. + + return nil +} + +func (o *OCS) getUI(U, Xc kyber.Point) (*share.PubShare, error) { + v := cothority.Suite.Point().Mul(o.Shared.V, U) + v.Add(v, cothority.Suite.Point().Mul(o.Shared.V, Xc)) + return &share.PubShare{ + I: o.Shared.Index, + V: v, + }, nil +} + +func (o *OCS) finish(result bool) { + o.timeout.Stop() + select { + case o.Reencrypted <- result: + // suceeded + default: + // would have blocked because some other call to finish() + // beat us. + } + o.doneOnce.Do(func() { o.Done() }) +} diff --git a/ocs/protocol_struct.go b/ocs/protocol_struct.go new file mode 100644 index 0000000000..5e3e0dd713 --- /dev/null +++ b/ocs/protocol_struct.go @@ -0,0 +1,53 @@ +package ocs + +/* +OCS_struct holds all messages for the onchain-secret protocol. +*/ + +import ( + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/share" + "go.dedis.ch/onet/v3" + "go.dedis.ch/onet/v3/network" +) + +// NameOCS can be used from other packages to refer to this protocol. +const NameOCS = "OCS" + +func init() { + network.RegisterMessages(&Reencrypt{}, &ReencryptReply{}) +} + +// VerifyRequest is a callback-function that can be set by a service. +// Whenever a reencryption request is received, this function will be +// called and its return-value used to determine whether or not to +// allow reencryption. +type VerifyRequest func(rc *Reencrypt) bool + +// Reencrypt asks for a re-encryption share from a node +type Reencrypt struct { + // U is the point from the write-request + U kyber.Point + // Xc is the public key of the reader + Xc kyber.Point + // VerificationData is optional and can be any slice of bytes, so that each + // node can verify if the reencryption request is valid or not. + VerificationData *[]byte +} + +type structReencrypt struct { + *onet.TreeNode + Reencrypt +} + +// ReencryptReply returns the share to re-encrypt from one node +type ReencryptReply struct { + Ui *share.PubShare + Ei kyber.Scalar + Fi kyber.Scalar +} + +type structReencryptReply struct { + *onet.TreeNode + ReencryptReply +} diff --git a/ocs/protocol_test.go b/ocs/protocol_test.go new file mode 100644 index 0000000000..a54721828a --- /dev/null +++ b/ocs/protocol_test.go @@ -0,0 +1,460 @@ +package ocs + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "errors" + "io" + "testing" + "time" + + "github.com/stretchr/testify/require" + "go.dedis.ch/cothority/v3" + dkgprotocol "go.dedis.ch/cothority/v3/dkg/pedersen" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/share" + dkg "go.dedis.ch/kyber/v3/share/dkg/pedersen" + "go.dedis.ch/kyber/v3/suites" + "go.dedis.ch/kyber/v3/util/key" + "go.dedis.ch/kyber/v3/util/random" + "go.dedis.ch/onet/v3" + "go.dedis.ch/onet/v3/log" +) + +var tSuite = cothority.Suite + +// Used for tests +var testServiceID onet.ServiceID + +const testServiceName = "ServiceOCS" + +func init() { + var err error + testServiceID, err = onet.RegisterNewService(testServiceName, newService) + log.ErrFatal(err) +} + +// Tests a 3, 5 and 13-node system. +func TestOCS(t *testing.T) { + nodes := []int{3} + // nodes := []int{3, 5, 10} + for _, nbrNodes := range nodes { + log.Lvlf1("Starting setupDKG with %d nodes", nbrNodes) + ocs(t, nbrNodes, nbrNodes-1, 32, 0, false) + } +} + +// Tests a system with failing nodes +func TestFail(t *testing.T) { + ocs(t, 4, 2, 32, 2, false) +} + +// Tests what happens if the nodes refuse to send their share +func TestRefuse(t *testing.T) { + log.Lvl1("Starting setupDKG with 3 nodes and refusing to sign") + ocs(t, 3, 2, 32, 0, true) +} + +func TestOCSKeyLengths(t *testing.T) { + if testing.Short() { + t.Skip("Testing all keylengths takes some time...") + } + for keylen := 1; keylen < 64; keylen++ { + log.Lvl1("Testing keylen of", keylen) + ocs(t, 3, 2, keylen, 0, false) + } +} + +var suite = suites.MustFind("Ed25519") + +func TestOnchain(t *testing.T) { + // 1 - share generation + nbrPeers := 5 + threshold := 3 + dkgs, err := CreateDKGs(suite.(dkg.Suite), nbrPeers, threshold) + log.ErrFatal(err) + + // Get aggregate public share + dks, err := dkgs[0].DistKeyShare() + log.ErrFatal(err) + X := dks.Public() + + // 5.1.2 - Encryption + data := []byte("Very secret Message to be encrypted") + var k [16]byte + random.Bytes(k[:], random.New()) + + encData, err := aeadSeal(k[:], data) + if err != nil { + t.Fatal(err) + } + U, Cs := EncodeKey(suite, X, k[:]) + // U and Cs is shared with everybody + + // Reader's keypair + xc := key.NewKeyPair(cothority.Suite) + + // Decryption + Ui := make([]*share.PubShare, nbrPeers) + for i := range Ui { + dks, err := dkgs[i].DistKeyShare() + log.ErrFatal(err) + v := suite.Point().Mul(dks.Share.V, U) + v.Add(v, suite.Point().Mul(dks.Share.V, xc.Public)) + Ui[i] = &share.PubShare{ + I: i, + V: v, + } + } + + // XhatEnc is the re-encrypted share under the reader's public key + XhatEnc, err := share.RecoverCommit(suite, Ui, threshold, nbrPeers) + log.ErrFatal(err) + + // Decrypt XhatEnc + keyHat, err := DecodeKey(suite, X, Cs, XhatEnc, xc.Private) + log.ErrFatal(err) + + // Extract the message - keyHat is the recovered key + log.Lvl2(encData) + dataHat, err := aeadOpen(keyHat, encData) + if err != nil { + t.Fatal(err) + } + require.Equal(t, data, dataHat) + log.Lvl1("Original data", string(data)) + log.Lvl1("Recovered data", string(dataHat)) +} + +// CreateDKGs is used for testing to set up a set of DKGs. +// +// Input: +// - suite - the suite to use +// - nbrNodes - how many nodes to set up +// - threshold - how many nodes can recover the secret +// +// Output: +// - dkgs - a slice of dkg-structures +// - err - an eventual error +func CreateDKGs(suite dkg.Suite, nbrNodes, threshold int) (dkgs []*dkg.DistKeyGenerator, err error) { + // 1 - share generation + dkgs = make([]*dkg.DistKeyGenerator, nbrNodes) + scalars := make([]kyber.Scalar, nbrNodes) + points := make([]kyber.Point, nbrNodes) + // 1a - initialisation + for i := range scalars { + scalars[i] = suite.Scalar().Pick(suite.RandomStream()) + points[i] = suite.Point().Mul(scalars[i], nil) + } + + // 1b - key-sharing + for i := range dkgs { + dkgs[i], err = dkg.NewDistKeyGenerator(suite, + scalars[i], points, threshold) + if err != nil { + return + } + } + // Exchange of Deals + responses := make([][]*dkg.Response, nbrNodes) + for i, p := range dkgs { + responses[i] = make([]*dkg.Response, nbrNodes) + deals, err := p.Deals() + if err != nil { + return nil, err + } + for j, d := range deals { + responses[i][j], err = dkgs[j].ProcessDeal(d) + if err != nil { + return nil, err + } + } + } + // ProcessResponses + for i, resp := range responses { + for j, r := range resp { + for k, p := range dkgs { + if r != nil && j != k { + log.Lvl3("Response from-to-peer:", i, j, k) + justification, err := p.ProcessResponse(r) + if err != nil { + return nil, err + } + if justification != nil { + return nil, errors.New("there should be no justification") + } + } + } + } + } + + // Verify if all is OK + for _, p := range dkgs { + if !p.Certified() { + return nil, errors.New("one of the dkgs is not finished yet") + } + } + return +} + +// These functions encapsulate the kind-of messy-to-use +// Go stdlib AEAD functions. We used to use the AEAD from crypto.v0, +// but it has been removed in preference to the standard one for now. +// +// If we want to use it in more places, it should be cleaned up, +// and moved to a permanent home. + +// This suggested length is from https://godoc.org/crypto/cipher#NewGCM example +const nonceLen = 12 + +func aeadSeal(symKey, data []byte) ([]byte, error) { + block, err := aes.NewCipher(symKey) + if err != nil { + return nil, err + } + + // Never use more than 2^32 random nonces with a given key because of the risk of a repeat. + nonce := make([]byte, nonceLen) + _, err = io.ReadFull(rand.Reader, nonce) + if err != nil { + return nil, err + } + + aesgcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + encData := aesgcm.Seal(nil, nonce, data, nil) + encData = append(encData, nonce...) + return encData, nil +} + +func aeadOpen(key, ciphertext []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + aesgcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + log.ErrFatal(err) + + if len(ciphertext) < 12 { + return nil, errors.New("ciphertext too short") + } + nonce := ciphertext[len(ciphertext)-nonceLen:] + out, err := aesgcm.Open(nil, nonce, ciphertext[0:len(ciphertext)-nonceLen], nil) + return out, err +} + +func ocs(t *testing.T, nbrNodes, threshold, keylen, fail int, refuse bool) { + local := onet.NewLocalTest(tSuite) + defer local.CloseAll() + servers, _, tree := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) + log.Lvl3(tree.Dump()) + + // 1 - setting up - in real life uses Setup-protocol + // Store the dkgs in the services + dkgs, err := CreateDKGs(tSuite.(dkg.Suite), nbrNodes, threshold) + require.Nil(t, err) + services := local.GetServices(servers, testServiceID) + for i := range services { + services[i].(*testService).Shared, _, err = dkgprotocol.NewSharedSecret(dkgs[i]) + require.Nil(t, err) + } + + // Get the collective public key + dks, err := dkgs[0].DistKeyShare() + require.Nil(t, err) + X := dks.Public() + + // 2 - writer - Encrypt a symmetric key and publish U, Cs + k := make([]byte, keylen) + random.Bytes(k, random.New()) + U, Cs := EncodeKey(tSuite, X, k) + + // 3 - reader - Makes a request to U by giving his public key Xc + // xc is the client's private/publick key pair + xc := key.NewKeyPair(cothority.Suite) + + // 4 - service - starts the protocol - + // as every node needs to have its own DKG, we + // use a service to give the corresponding DKGs to the nodes. + + // First stop the nodes that should fail + for _, s := range servers[1 : 1+fail] { + log.Lvl1("Pausing", s.ServerIdentity) + s.Pause() + } + pi, err := services[0].(*testService).createOCS(tree, threshold) + require.Nil(t, err) + protocol := pi.(*OCS) + protocol.U = U + protocol.Xc = xc.Public + protocol.Poly = share.NewPubPoly(suite, suite.Point().Base(), dks.Commits) + if !refuse { + protocol.VerificationData = []byte("correct block") + } + // timeout := network.WaitRetry * time.Duration(network.MaxRetryConnect*nbrNodes*2) * time.Millisecond + require.Nil(t, protocol.Start()) + select { + case <-protocol.Reencrypted: + log.Lvl2("root-node is done") + // Wait for other nodes + case <-time.After(time.Second): + t.Fatal("Didn't finish in time") + } + + // 5 - service - Lagrange interpolate the Uis - the reader will only + // get XhatEnc + var XhatEnc kyber.Point + if refuse { + require.Nil(t, protocol.Uis, "Reencrypted request that should've been refused") + return + } + + require.NotNil(t, protocol.Uis) + XhatEnc, err = share.RecoverCommit(suite, protocol.Uis, threshold, nbrNodes) + require.Nil(t, err, "Reencryption failed") + + // 6 - reader - gets the resulting symmetric key, encrypted under Xc + keyHat, err := DecodeKey(suite, X, Cs, XhatEnc, xc.Private) + require.Nil(t, err) + + require.Equal(t, k, keyHat) +} + +// testService allows setting the dkg-field of the protocol. +type testService struct { + // We need to embed the ServiceProcessor, so that incoming messages + // are correctly handled. + *onet.ServiceProcessor + + // Has to be initialised by the test + Shared *dkgprotocol.SharedSecret + Poly *share.PubPoly +} + +// Creates a service-protocol and returns the ProtocolInstance. +func (s *testService) createOCS(t *onet.Tree, threshold int) (onet.ProtocolInstance, error) { + pi, err := s.CreateProtocol(NameOCS, t) + pi.(*OCS).Shared = s.Shared + pi.(*OCS).Poly = s.Poly + pi.(*OCS).Threshold = threshold + return pi, err +} + +// Store the dkg in the protocol +func (s *testService) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfig) (onet.ProtocolInstance, error) { + switch tn.ProtocolName() { + case NameOCS: + pi, err := NewOCS(tn) + if err != nil { + return nil, err + } + ocs := pi.(*OCS) + ocs.Shared = s.Shared + ocs.Verify = func(rc *Reencrypt) bool { + return rc.VerificationData != nil + } + return ocs, nil + default: + return nil, errors.New("unknown protocol for this service") + } +} + +// EncodeKey can be used by the writer to an onchain-secret skipchain +// to encode his symmetric key under the collective public key created +// by the DKG. +// As this method uses `Pick` to encode the key, depending on the key-length +// more than one point is needed to encode the data. +// +// Input: +// - suite - the cryptographic suite to use +// - X - the aggregate public key of the DKG +// - key - the symmetric key for the document +// +// Output: +// - U - the schnorr commit +// - Cs - encrypted key-slices +func EncodeKey(suite suites.Suite, X kyber.Point, key []byte) (U kyber.Point, Cs []kyber.Point) { + r := suite.Scalar().Pick(suite.RandomStream()) + C := suite.Point().Mul(r, X) + log.Lvl3("C:", C.String()) + U = suite.Point().Mul(r, nil) + log.Lvl3("U is:", U.String()) + + for len(key) > 0 { + var kp kyber.Point + kp = suite.Point().Embed(key, suite.RandomStream()) + log.Lvl3("Keypoint:", kp.String()) + log.Lvl3("X:", X.String()) + Cs = append(Cs, suite.Point().Add(C, kp)) + log.Lvl3("Cs:", C.String()) + key = key[min(len(key), kp.EmbedLen()):] + } + return +} + +// DecodeKey can be used by the reader of an onchain-secret to convert the +// re-encrypted secret back to a symmetric key that can be used later to +// decode the document. +// +// Input: +// - suite - the cryptographic suite to use +// - X - the aggregate public key of the DKG +// - Cs - the encrypted key-slices +// - XhatEnc - the re-encrypted schnorr-commit +// - xc - the private key of the reader +// +// Output: +// - key - the re-assembled key +// - err - an eventual error when trying to recover the data from the points +func DecodeKey(suite kyber.Group, X kyber.Point, Cs []kyber.Point, XhatEnc kyber.Point, + xc kyber.Scalar) (key []byte, err error) { + log.Lvl3("xc:", xc) + xcInv := suite.Scalar().Neg(xc) + log.Lvl3("xcInv:", xcInv) + sum := suite.Scalar().Add(xc, xcInv) + log.Lvl3("xc + xcInv:", sum, "::", xc) + log.Lvl3("X:", X) + XhatDec := suite.Point().Mul(xcInv, X) + log.Lvl3("XhatDec:", XhatDec) + log.Lvl3("XhatEnc:", XhatEnc) + Xhat := suite.Point().Add(XhatEnc, XhatDec) + log.Lvl3("Xhat:", Xhat) + XhatInv := suite.Point().Neg(Xhat) + log.Lvl3("XhatInv:", XhatInv) + + // Decrypt Cs to keyPointHat + for _, C := range Cs { + log.Lvl3("C:", C) + keyPointHat := suite.Point().Add(C, XhatInv) + log.Lvl3("keyPointHat:", keyPointHat) + keyPart, err := keyPointHat.Data() + log.Lvl3("keyPart:", keyPart) + if err != nil { + return nil, err + } + key = append(key, keyPart...) + } + return +} + +// starts a new service. No function needed. +func newService(c *onet.Context) (onet.Service, error) { + s := &testService{ + ServiceProcessor: onet.NewServiceProcessor(c), + } + return s, nil +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/ocs/service.go b/ocs/service.go new file mode 100644 index 0000000000..05ae31988f --- /dev/null +++ b/ocs/service.go @@ -0,0 +1,619 @@ +// Package OCS is a general-purpose re-encryption service that can be used +// either in ByzCoin with the Calypso-service and its contracts, or with +// Ethereum/Fabric. It is extensible to work also with other kind of +// Access-control backends, e.g., Ethereum. +package ocs + +import ( + "errors" + "fmt" + "net" + "net/http" + "os" + "time" + + "go.dedis.ch/cothority/v3" + "go.dedis.ch/cothority/v3/byzcoin" + "go.dedis.ch/cothority/v3/darc" + dkgprotocol "go.dedis.ch/cothority/v3/dkg/pedersen" + "go.dedis.ch/cothority/v3/ocs/protocol" + "go.dedis.ch/cothority/v3/skipchain" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/share" + dkg "go.dedis.ch/kyber/v3/share/dkg/pedersen" + "go.dedis.ch/kyber/v3/util/key" + "go.dedis.ch/onet/v3" + "go.dedis.ch/onet/v3/log" + "go.dedis.ch/onet/v3/network" + "go.dedis.ch/protobuf" +) + +// Used for tests +var OCSServiceID onet.ServiceID + +// ServiceName of the secret-management part of Calypso. +const ServiceName = "OCS" + +// dkgTimeout is how long the system waits for the DKG to finish +const propagationTimeout = 20 * time.Second + +const calypsoReshareProto = "calypso_reshare_proto" + +var disableLoopbackCheck = false + +func init() { + var err error + _, err = onet.GlobalProtocolRegister(calypsoReshareProto, dkgprotocol.NewSetup) + log.ErrFatal(err) + OCSServiceID, err = onet.RegisterNewService(ServiceName, newService) + log.ErrFatal(err) + network.RegisterMessages(&storage{}, &vData{}) + + // The loopback check makes Java testing not work, because Java client commands + // come from outside of the docker container. The Java testing Docker + // container runs with this variable set. + if os.Getenv("COTHORITY_ALLOW_INSECURE_ADMIN") != "" { + log.Warn("COTHORITY_ALLOW_INSECURE_ADMIN is set; Calypso admin actions allowed from the public network.") + disableLoopbackCheck = true + } +} + +// Service is our calypso-service. It stores all created LTSs. +type Service struct { + *onet.ServiceProcessor + storage *storage + afterReshare func() // for use by testing only +} + +// pubPoly is a serializable version of share.PubPoly +type pubPoly struct { + B kyber.Point + Commits []kyber.Point +} + +// vData is sent to all nodes when re-encryption takes place. If Ephemeral +// is non-nil, Signature needs to hold a valid signature from the reader +// in the Proof. +type vData struct { + Proof byzcoin.Proof + Ephemeral kyber.Point + Signature *darc.Signature +} + +// ProcessClientRequest implements onet.Service. We override the version +// we normally get from embeddeding onet.ServiceProcessor in order to +// hook it and get a look at the http.Request. +func (s *Service) ProcessClientRequest(req *http.Request, path string, buf []byte) ([]byte, *onet.StreamingTunnel, error) { + if !disableLoopbackCheck && path == "Authorise" { + h, _, err := net.SplitHostPort(req.RemoteAddr) + if err != nil { + return nil, nil, err + } + ip := net.ParseIP(h) + + if !ip.IsLoopback() { + return nil, nil, errors.New("authorise is only allowed on loopback") + } + } + + return s.ServiceProcessor.ProcessClientRequest(req, path, buf) +} + +// Authorise adds a ByzCoinID to the list of authorized IDs. It should +// be called by the administrator at the beginning, before any other API calls +// are made. A ByzCoinID that is not authorised will not be allowed to call the +// other APIs. +func (s *Service) Authorise(req *Authorise) (*AuthoriseReply, error) { + s.storage.Lock() + defer s.storage.Unlock() + if len(req.ByzCoinID) == 0 { + return nil, errors.New("empty ByzCoin ID") + } + key := string(req.ByzCoinID) + if _, ok := s.storage.AuthorisedByzCoinIDs[key]; ok { + return nil, errors.New("ByzCoinID already authorised") + } + s.storage.AuthorisedByzCoinIDs[key] = true + return &AuthoriseReply{}, nil +} + +// CreateLTS takes as input a roster with a list of all nodes that should +// participate in the DKG. Every node will store its private key and wait for +// decryption requests. The OCSID should be the InstanceID. +func (s *Service) CreateLTS(req *CreateLTS) (reply *CreateLTSReply, err error) { + if err := s.verifyProof(&req.Proof, nil); err != nil { + return nil, err + } + + roster, instID, err := s.getLtsRoster(&req.Proof) + if err != nil { + return nil, err + } + + // NOTE: the roster stored in ByzCoin must have myself. + tree := roster.GenerateNaryTreeWithRoot(len(roster.List), s.ServerIdentity()) + cfg := newLtsConfig{ + req.Proof, + } + cfgBuf, err := protobuf.Encode(&cfg) + if err != nil { + return nil, err + } + pi, err := s.CreateProtocol(dkgprotocol.Name, tree) + if err != nil { + return nil, err + } + setupDKG := pi.(*dkgprotocol.Setup) + setupDKG.Wait = true + setupDKG.SetConfig(&onet.GenericConfig{Data: cfgBuf}) + setupDKG.KeyPair = s.getKeyPair() + + if err := pi.Start(); err != nil { + return nil, err + } + + log.Lvl3("Started DKG-protocol - waiting for done", len(roster.List)) + select { + case <-setupDKG.Finished: + shared, dks, err := setupDKG.SharedSecret() + if err != nil { + return nil, err + } + reply = &CreateLTSReply{ + ByzCoinID: req.Proof.Latest.SkipChainID(), + InstanceID: instID, + X: shared.X, + } + s.storage.Lock() + s.storage.Shared[instID] = shared + s.storage.Polys[instID] = &pubPoly{s.Suite().Point().Base(), dks.Commits} + s.storage.Rosters[instID] = roster + s.storage.Replies[instID] = reply + s.storage.DKS[instID] = dks + s.storage.Unlock() + s.save() + log.Lvlf2("%v Created LTS with ID: %v, pk %v", s.ServerIdentity(), instID, reply.X) + case <-time.After(propagationTimeout): + return nil, errors.New("new-dkg didn't finish in time") + } + return +} + +// ReshareLTS starts a request to reshare the LTS. The new roster which holds +// the new secret shares must exist in the proof specified by the request. +// All hosts must be online in this step. +func (s *Service) ReshareLTS(req *ReshareLTS) (*ReshareLTSReply, error) { + // Verify the request + roster, id, err := s.getLtsRoster(&req.Proof) + if err != nil { + return nil, err + } + if err := s.verifyProof(&req.Proof, roster); err != nil { + return nil, err + } + + // Initialise the protocol + setupDKG, err := func() (*dkgprotocol.Setup, error) { + s.storage.Lock() + defer s.storage.Unlock() + + // Check that we know the shared secret, otherwise don't do re-sharing + if s.storage.Shared[id] == nil || s.storage.DKS[id] == nil { + return nil, errors.New("cannot start resharing without an LTS") + } + + // NOTE: the roster stored in ByzCoin must have myself. + tree := roster.GenerateNaryTreeWithRoot(len(roster.List), s.ServerIdentity()) + cfg := reshareLtsConfig{ + Proof: req.Proof, + // We pass the public coefficients out with the protocol, + // because new nodes will need it for their dkg.Config.PublicCoeffs. + Commits: s.storage.DKS[id].Commits, + OldNodes: s.storage.Rosters[id].Publics(), + } + cfgBuf, err := protobuf.Encode(&cfg) + if err != nil { + return nil, err + } + pi, err := s.CreateProtocol(calypsoReshareProto, tree) + if err != nil { + return nil, err + } + setupDKG := pi.(*dkgprotocol.Setup) + setupDKG.Wait = true + setupDKG.KeyPair = s.getKeyPair() + setupDKG.SetConfig(&onet.GenericConfig{Data: cfgBuf}) + + // Because we are the node starting the resharing protocol, by + // definition, we are inside the old group. (Checked first thing + // in this function.) So we have only Share, not PublicCoeffs. + n := len(roster.List) + c := &dkg.Config{ + Suite: cothority.Suite, + Longterm: setupDKG.KeyPair.Private, + OldNodes: s.storage.Rosters[id].Publics(), + NewNodes: roster.Publics(), + Share: s.storage.DKS[id], + Threshold: n - (n-1)/3, + } + setupDKG.NewDKG = func() (*dkg.DistKeyGenerator, error) { + d, err := dkg.NewDistKeyHandler(c) + return d, err + } + return setupDKG, nil + }() + if err != nil { + return nil, err + } + if err := setupDKG.Start(); err != nil { + return nil, err + } + log.Lvl3(s.ServerIdentity(), "Started resharing DKG-protocol - waiting for done") + + var pk kyber.Point + select { + case <-setupDKG.Finished: + shared, dks, err := setupDKG.SharedSecret() + if err != nil { + return nil, err + } + pk = shared.X + s.storage.Lock() + // Check the secret shares are different + if shared.V.Equal(s.storage.Shared[id].V) { + s.storage.Unlock() + return nil, errors.New("the reshared secret is the same") + } + // Check the public key remains the same + if !shared.X.Equal(s.storage.Shared[id].X) { + s.storage.Unlock() + return nil, errors.New("the reshared public point is different") + } + s.storage.Shared[id] = shared + s.storage.Polys[id] = &pubPoly{s.Suite().Point().Base(), dks.Commits} + s.storage.Rosters[id] = roster + s.storage.DKS[id] = dks + s.storage.Unlock() + s.save() + if s.afterReshare != nil { + s.afterReshare() + } + case <-time.After(propagationTimeout): + return nil, errors.New("resharing-dkg didn't finish in time") + } + + log.Lvl2(s.ServerIdentity(), "resharing protocol finished") + log.Lvlf2("%v Reshared LTS with ID: %v, pk %v", s.ServerIdentity(), id, pk) + return &ReshareLTSReply{}, nil +} + +func (s *Service) verifyProof(proof *byzcoin.Proof, roster *onet.Roster) error { + scID := proof.Latest.SkipChainID() + s.storage.Lock() + defer s.storage.Unlock() + if _, ok := s.storage.AuthorisedByzCoinIDs[string(scID)]; !ok { + return errors.New("this ByzCoin ID is not authorised") + } + + // We used to check that the roster ID did not change here, but with + // resharing, it is expected that the roster can change. + // TODO: Confirm with Kelong that this is correct to remove; that this + // does not open us up to abuse/attack. + + return proof.Verify(scID) +} + +func (s *Service) getLtsRoster(proof *byzcoin.Proof) (*onet.Roster, byzcoin.InstanceID, error) { + instanceID, buf, _, _, err := proof.KeyValue() + if err != nil { + return nil, byzcoin.InstanceID{}, err + } + + var info LtsInstanceInfo + err = protobuf.DecodeWithConstructors(buf, &info, network.DefaultConstructors(cothority.Suite)) + if err != nil { + return nil, byzcoin.InstanceID{}, err + } + return &info.Roster, byzcoin.NewInstanceID(instanceID), nil +} + +// DecryptKey takes as an input a Read- and a Write-proof. Proofs contain +// everything necessary to verify that a given instance is correct and +// stored in ByzCoin. +// Using the Read and the Write-instance, this method verifies that the +// requests match and then re-encrypts the secret to the public key given +// in the Read-instance. +func (s *Service) DecryptKey(dkr *DecryptKey) (reply *DecryptKeyReply, err error) { + reply = &DecryptKeyReply{} + log.Lvl2(s.ServerIdentity(), "Re-encrypt the key to the public key of the reader") + + var read Read + if err := dkr.Read.VerifyAndDecode(cothority.Suite, ContractReadID, &read); err != nil { + return nil, errors.New("didn't get a read instance: " + err.Error()) + } + + var write Write + if err := dkr.Write.VerifyAndDecode(cothority.Suite, ContractWriteID, &write); err != nil { + return nil, errors.New("didn't get a write instance: " + err.Error()) + } + if !read.Write.Equal(byzcoin.NewInstanceID(dkr.Write.InclusionProof.Key())) { + return nil, errors.New("read doesn't point to passed write") + } + s.storage.Lock() + id := write.LTSID + roster := s.storage.Rosters[id] + if roster == nil { + s.storage.Unlock() + return nil, fmt.Errorf("don't know the OCSID '%v' stored in write", id) + } + scID := make([]byte, 32) + copy(scID, s.storage.Replies[id].ByzCoinID) + s.storage.Unlock() + if err = dkr.Read.Verify(scID); err != nil { + return nil, errors.New("read proof cannot be verified to come from scID: " + err.Error()) + } + if err = dkr.Write.Verify(scID); err != nil { + return nil, errors.New("write proof cannot be verified to come from scID: " + err.Error()) + } + + // Start ocs-protocol to re-encrypt the file's symmetric key under the + // reader's public key. + nodes := len(roster.List) + threshold := nodes - (nodes-1)/3 + tree := roster.GenerateNaryTreeWithRoot(nodes, s.ServerIdentity()) + pi, err := s.CreateProtocol(protocol.NameOCS, tree) + if err != nil { + return nil, err + } + ocsProto := pi.(*protocol.OCS) + ocsProto.U = write.U + verificationData := &vData{ + Proof: dkr.Read, + } + ocsProto.Xc = read.Xc + log.Lvlf2("%v Public key is: %s", s.ServerIdentity(), ocsProto.Xc) + ocsProto.VerificationData, err = protobuf.Encode(verificationData) + if err != nil { + return nil, errors.New("couldn't marshal verification data: " + err.Error()) + } + + // Make sure everything used from the s.Storage structure is copied, so + // there will be no races. + s.storage.Lock() + ocsProto.Shared = s.storage.Shared[id] + pp := s.storage.Polys[id] + reply.X = s.storage.Shared[id].X.Clone() + var commits []kyber.Point + for _, c := range pp.Commits { + commits = append(commits, c.Clone()) + } + ocsProto.Poly = share.NewPubPoly(s.Suite(), pp.B.Clone(), commits) + s.storage.Unlock() + + log.Lvl3("Starting reencryption protocol") + ocsProto.SetConfig(&onet.GenericConfig{Data: id.Slice()}) + err = ocsProto.Start() + if err != nil { + return nil, err + } + if !<-ocsProto.Reencrypted { + return nil, errors.New("reencryption got refused") + } + log.Lvl3("Reencryption protocol is done.") + reply.XhatEnc, err = share.RecoverCommit(cothority.Suite, ocsProto.Uis, + threshold, nodes) + if err != nil { + return nil, err + } + reply.C = write.C + log.Lvl3("Successfully reencrypted the key") + return +} + +// GetLTSReply returns the CreateLTSReply message of a previous LTS. +func (s *Service) GetLTSReply(req *GetLTSReply) (*CreateLTSReply, error) { + log.Lvlf2("Getting LTS Reply for ID: %v", req.LTSID) + s.storage.Lock() + defer s.storage.Unlock() + reply, ok := s.storage.Replies[req.LTSID] + if !ok { + return nil, fmt.Errorf("didn't find this LTS: %v", req.LTSID) + } + return &CreateLTSReply{ + ByzCoinID: append([]byte{}, reply.ByzCoinID...), + InstanceID: reply.InstanceID, + X: reply.X.Clone(), + }, nil +} + +func (s *Service) getKeyPair() *key.Pair { + tree := onet.NewRoster([]*network.ServerIdentity{s.ServerIdentity()}).GenerateBinaryTree() + tni := s.NewTreeNodeInstance(tree, tree.Root, "dummy") + return &key.Pair{ + Public: tni.Public(), + Private: tni.Private(), + } +} + +// NewProtocol intercepts the DKG and OCS protocols to retrieve the values +func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfig) (onet.ProtocolInstance, error) { + log.Lvl3(s.ServerIdentity(), tn.ProtocolName(), conf) + switch tn.ProtocolName() { + case dkgprotocol.Name: + var cfg newLtsConfig + if err := protobuf.DecodeWithConstructors(conf.Data, &cfg, network.DefaultConstructors(cothority.Suite)); err != nil { + return nil, err + } + if err := s.verifyProof(&cfg.Proof, tn.Roster()); err != nil { + return nil, err + } + key, _, _, _, err := cfg.KeyValue() + if err != nil { + return nil, err + } + instID := byzcoin.NewInstanceID(key) + + pi, err := dkgprotocol.NewSetup(tn) + if err != nil { + return nil, err + } + setupDKG := pi.(*dkgprotocol.Setup) + setupDKG.KeyPair = s.getKeyPair() + + go func(bcID skipchain.SkipBlockID, id byzcoin.InstanceID) { + <-setupDKG.Finished + shared, dks, err := setupDKG.SharedSecret() + if err != nil { + log.Error(err) + return + } + reply := &CreateLTSReply{ + ByzCoinID: bcID, + InstanceID: instID, + X: shared.X, + } + log.Lvlf3("%v got shared %v on inst %v", s.ServerIdentity(), shared, id) + s.storage.Lock() + s.storage.Shared[id] = shared + s.storage.DKS[id] = dks + s.storage.Replies[id] = reply + s.storage.Rosters[id] = tn.Roster() + s.storage.Unlock() + s.save() + }(cfg.Latest.SkipChainID(), instID) + return pi, nil + case calypsoReshareProto: + // Decode and verify config + var cfg reshareLtsConfig + if err := protobuf.DecodeWithConstructors(conf.Data, &cfg, network.DefaultConstructors(cothority.Suite)); err != nil { + return nil, err + } + if err := s.verifyProof(&cfg.Proof, tn.Roster()); err != nil { + return nil, err + } + + _, id, err := s.getLtsRoster(&cfg.Proof) + + // Set up the protocol + pi, err := dkgprotocol.NewSetup(tn) + if err != nil { + return nil, err + } + setupDKG := pi.(*dkgprotocol.Setup) + setupDKG.KeyPair = s.getKeyPair() + + s.storage.Lock() + n := len(tn.Roster().List) + c := &dkg.Config{ + Suite: cothority.Suite, + Longterm: setupDKG.KeyPair.Private, + NewNodes: tn.Roster().Publics(), + OldNodes: cfg.OldNodes, + Threshold: n - (n-1)/3, + } + s.storage.Unlock() + + // Set Share and PublicCoeffs according to if we are an old node or a new one. + inOld := pointInList(setupDKG.KeyPair.Public, cfg.OldNodes) + if inOld { + c.Share = s.storage.DKS[id] + } else { + c.PublicCoeffs = cfg.Commits + } + + setupDKG.NewDKG = func() (*dkg.DistKeyGenerator, error) { + d, err := dkg.NewDistKeyHandler(c) + return d, err + } + + if err != nil { + return nil, err + } + + // Wait for DKG in reshare mode to end + go func(id byzcoin.InstanceID) { + <-setupDKG.Finished + shared, dks, err := setupDKG.SharedSecret() + if err != nil { + log.Error(err) + return + } + + s.storage.Lock() + // If we had an old share, check the new share before saving it. + if s.storage.Shared[id] != nil { + // Check the secret shares are different + if shared.V.Equal(s.storage.Shared[id].V) { + s.storage.Unlock() + log.Error("the reshared secret is the same") + return + } + + // Check the public key remains the same + if !shared.X.Equal(s.storage.Shared[id].X) { + s.storage.Unlock() + log.Error("the reshared public point is different") + return + } + } + s.storage.Shared[id] = shared + s.storage.DKS[id] = dks + s.storage.Unlock() + s.save() + if s.afterReshare != nil { + s.afterReshare() + } + }(id) + return setupDKG, nil + case protocol.NameOCS: + id := byzcoin.NewInstanceID(conf.Data) + s.storage.Lock() + shared, ok := s.storage.Shared[id] + shared = shared.Clone() + s.storage.Unlock() + if !ok { + return nil, fmt.Errorf("didn't find OCSID %v", id) + } + pi, err := protocol.NewOCS(tn) + if err != nil { + return nil, err + } + ocs := pi.(*protocol.OCS) + ocs.Shared = shared + ocs.Verify = s.verifyReencryption + return ocs, nil + } + return nil, nil +} + +func pointInList(p1 kyber.Point, l []kyber.Point) bool { + for _, p2 := range l { + if p2.Equal(p1) { + return true + } + } + return false +} + +// verifyReencryption checks that the read and the write instances match. +func (s *Service) verifyReencryption(rc *protocol.Reencrypt) bool { + return false +} + +// newService receives the context that holds information about the node it's +// running on. Saving and loading can be done using the context. The data will +// be stored in memory for tests and simulations, and on disk for real deployments. +func newService(c *onet.Context) (onet.Service, error) { + s := &Service{ + ServiceProcessor: onet.NewServiceProcessor(c), + } + if err := s.RegisterHandlers(s.CreateLTS, s.ReshareLTS, s.DecryptKey, + s.GetLTSReply, s.Authorise); err != nil { + return nil, errors.New("couldn't register messages") + } + if err := s.tryLoad(); err != nil { + log.Error(err) + return nil, err + } + return s, nil +} diff --git a/calypso/verify.go b/ocs/verify.go similarity index 98% rename from calypso/verify.go rename to ocs/verify.go index 3458414531..4e140847b9 100644 --- a/calypso/verify.go +++ b/ocs/verify.go @@ -1,4 +1,4 @@ -package calypso +package ocs import ( "crypto/x509" diff --git a/calypso/verify_test.go b/ocs/verify_test.go similarity index 99% rename from calypso/verify_test.go rename to ocs/verify_test.go index 86eb00751b..02666c9b58 100644 --- a/calypso/verify_test.go +++ b/ocs/verify_test.go @@ -1,4 +1,4 @@ -package calypso +package ocs import ( "crypto/x509" From 6cbd21ddfd7b3a68eb74d989b51fa1dbf84cc928 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Wed, 10 Apr 2019 08:43:27 +0200 Subject: [PATCH 03/21] adding resharing --- authprox/apadmin/main.go | 4 +- authprox/proto.go | 2 +- authprox/service.go | 2 +- calypso/protocol/ocs_struct.go | 2 +- darc/proto.go | 4 +- eventlog/el/main.go | 2 +- .../epfl/dedis/lib/proto/AuthProxProto.java | 4 +- .../ch/epfl/dedis/lib/proto/DarcProto.java | 8 +- .../java/ch/epfl/dedis/lib/proto/OCS.java | 7673 +++++++++++++---- external/proto/authprox.proto | 2 +- external/proto/darc.proto | 4 +- external/proto/ocs.proto | 93 +- ocs/api.go | 44 +- ocs/proto.go | 97 +- ocs/protocol.go | 6 +- ocs/protocol_struct.go | 14 +- skipchain/msgs.go | 4 +- skipchain/skipchain.go | 2 +- 18 files changed, 6217 insertions(+), 1750 deletions(-) diff --git a/authprox/apadmin/main.go b/authprox/apadmin/main.go index c4ef4a5dc0..9b1edc0679 100644 --- a/authprox/apadmin/main.go +++ b/authprox/apadmin/main.go @@ -28,7 +28,7 @@ var cmds = cli.Commands{ Flags: []cli.Flag{ cli.StringFlag{ Name: "roster, r", - Usage: "the roster of the cothority that hosts the distributed Authentication Proxy", + Usage: "the roster of the cothority that hosts the distributed Policy Proxy", }, cli.StringFlag{ Name: "type", @@ -48,7 +48,7 @@ var cmds = cli.Commands{ Flags: []cli.Flag{ cli.StringFlag{ Name: "roster, r", - Usage: "the roster of the cothority that hosts the distributed Authentication Proxy", + Usage: "the roster of the cothority that hosts the distributed Policy Proxy", }, }, Action: show, diff --git a/authprox/proto.go b/authprox/proto.go index 2e15b39d40..ce1309e9aa 100644 --- a/authprox/proto.go +++ b/authprox/proto.go @@ -24,7 +24,7 @@ type EnrollResponse struct { } // SignatureRequest is the request sent to this service to request that -// the Authentication Proxy check the authentication information and +// the Policy Proxy check the authentication information and // generate a signature connecting some information identifying the // holder of the AuthInfo to the message. type SignatureRequest struct { diff --git a/authprox/service.go b/authprox/service.go index 8bf5e0d2b2..335379339e 100644 --- a/authprox/service.go +++ b/authprox/service.go @@ -21,7 +21,7 @@ import ( bbolt "go.etcd.io/bbolt" ) -// ServiceName is the name of the Authentication Proxy service. +// ServiceName is the name of the Policy Proxy service. const ServiceName = "AuthProx" var authProxID onet.ServiceID diff --git a/calypso/protocol/ocs_struct.go b/calypso/protocol/ocs_struct.go index 56da88621b..eb5b70d928 100644 --- a/calypso/protocol/ocs_struct.go +++ b/calypso/protocol/ocs_struct.go @@ -40,7 +40,7 @@ type structReencrypt struct { Reencrypt } -// ReencryptReply returns the share to re-encrypt from one node +// MessageReencryptReply returns the share to re-encrypt from one node type ReencryptReply struct { Ui *share.PubShare Ei kyber.Scalar diff --git a/darc/proto.go b/darc/proto.go index 282e7f29e6..ff36bf39ce 100644 --- a/darc/proto.go +++ b/darc/proto.go @@ -77,7 +77,7 @@ type IdentityX509EC struct { } // IdentityProxy holds the info necessary to verify a claim -// from an external authentication system via an Authentication Proxy. +// from an external authentication system via an Policy Proxy. type IdentityProxy struct { Data string Public kyber.Point @@ -120,7 +120,7 @@ type SignerX509EC struct { } // SignerProxy holds the information necessary to verify claims -// coming from external authentication systems via Authentication Proxies. +// coming from external authentication systems via Policy Proxies. type SignerProxy struct { Data string Public kyber.Point diff --git a/eventlog/el/main.go b/eventlog/el/main.go index b845031a58..eead47d534 100644 --- a/eventlog/el/main.go +++ b/eventlog/el/main.go @@ -643,7 +643,7 @@ func (o *openidCfg) getSigners(cl *eventlog.Client) ([]darc.Signer, error) { n := len(r.List) T := threshold(n) - // The callback from darc.Sign where we need to go contact the Authentication Proxies. + // The callback from darc.Sign where we need to go contact the Policy Proxies. cb := func(msg []byte) ([]byte, error) { tok, err := ts.Token() if err != nil { diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/AuthProxProto.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/AuthProxProto.java index 975c725ae6..ece1791d9d 100644 --- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/AuthProxProto.java +++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/AuthProxProto.java @@ -1799,7 +1799,7 @@ public interface SignatureRequestOrBuilder extends /** *
    * SignatureRequest is the request sent to this service to request that
-   * the Authentication Proxy check the authentication information and
+   * the Policy Proxy check the authentication information and
    * generate a signature connecting some information identifying the
    * holder of the AuthInfo to the message.
    * 
@@ -2346,7 +2346,7 @@ protected Builder newBuilderForType( /** *
      * SignatureRequest is the request sent to this service to request that
-     * the Authentication Proxy check the authentication information and
+     * the Policy Proxy check the authentication information and
      * generate a signature connecting some information identifying the
      * holder of the AuthInfo to the message.
      * 
diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/DarcProto.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/DarcProto.java index 942bb2861b..57187a366c 100644 --- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/DarcProto.java +++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/DarcProto.java @@ -4927,7 +4927,7 @@ public interface IdentityProxyOrBuilder extends /** *
    * IdentityProxy holds the info necessary to verify a claim
-   * from an external authentication system via an Authentication Proxy.
+   * from an external authentication system via an Policy Proxy.
    * 
* * Protobuf type {@code darc.IdentityProxy} @@ -5257,7 +5257,7 @@ protected Builder newBuilderForType( /** *
      * IdentityProxy holds the info necessary to verify a claim
-     * from an external authentication system via an Authentication Proxy.
+     * from an external authentication system via an Policy Proxy.
      * 
* * Protobuf type {@code darc.IdentityProxy} @@ -9206,7 +9206,7 @@ public interface SignerProxyOrBuilder extends /** *
    * SignerProxy holds the information necessary to verify claims
-   * coming from external authentication systems via Authentication Proxies.
+   * coming from external authentication systems via Policy Proxies.
    * 
* * Protobuf type {@code darc.SignerProxy} @@ -9536,7 +9536,7 @@ protected Builder newBuilderForType( /** *
      * SignerProxy holds the information necessary to verify claims
-     * coming from external authentication systems via Authentication Proxies.
+     * coming from external authentication systems via Policy Proxies.
      * 
* * Protobuf type {@code darc.SignerProxy} diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java index f2b1e40b9e..81e292173a 100644 --- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java +++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java @@ -32,17 +32,17 @@ public interface CreateOCSOrBuilder extends ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder(); /** - * required .ocs.Auth authentication = 2; + * required .ocs.Policy policy = 2; */ - boolean hasAuthentication(); + boolean hasPolicy(); /** - * required .ocs.Auth authentication = 2; + * required .ocs.Policy policy = 2; */ - ch.epfl.dedis.lib.proto.OCS.Auth getAuthentication(); + ch.epfl.dedis.lib.proto.OCS.Policy getPolicy(); /** - * required .ocs.Auth authentication = 2; + * required .ocs.Policy policy = 2; */ - ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder getAuthenticationOrBuilder(); + ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyOrBuilder(); } /** *
@@ -101,14 +101,14 @@ private CreateOCS(
               break;
             }
             case 18: {
-              ch.epfl.dedis.lib.proto.OCS.Auth.Builder subBuilder = null;
+              ch.epfl.dedis.lib.proto.OCS.Policy.Builder subBuilder = null;
               if (((bitField0_ & 0x00000002) != 0)) {
-                subBuilder = authentication_.toBuilder();
+                subBuilder = policy_.toBuilder();
               }
-              authentication_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Auth.parser(), extensionRegistry);
+              policy_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Policy.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(authentication_);
-                authentication_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(policy_);
+                policy_ = subBuilder.buildPartial();
               }
               bitField0_ |= 0x00000002;
               break;
@@ -167,25 +167,25 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() {
       return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_;
     }
 
-    public static final int AUTHENTICATION_FIELD_NUMBER = 2;
-    private ch.epfl.dedis.lib.proto.OCS.Auth authentication_;
+    public static final int POLICY_FIELD_NUMBER = 2;
+    private ch.epfl.dedis.lib.proto.OCS.Policy policy_;
     /**
-     * required .ocs.Auth authentication = 2;
+     * required .ocs.Policy policy = 2;
      */
-    public boolean hasAuthentication() {
+    public boolean hasPolicy() {
       return ((bitField0_ & 0x00000002) != 0);
     }
     /**
-     * required .ocs.Auth authentication = 2;
+     * required .ocs.Policy policy = 2;
      */
-    public ch.epfl.dedis.lib.proto.OCS.Auth getAuthentication() {
-      return authentication_ == null ? ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance() : authentication_;
+    public ch.epfl.dedis.lib.proto.OCS.Policy getPolicy() {
+      return policy_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policy_;
     }
     /**
-     * required .ocs.Auth authentication = 2;
+     * required .ocs.Policy policy = 2;
      */
-    public ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder getAuthenticationOrBuilder() {
-      return authentication_ == null ? ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance() : authentication_;
+    public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyOrBuilder() {
+      return policy_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policy_;
     }
 
     private byte memoizedIsInitialized = -1;
@@ -199,7 +199,7 @@ public final boolean isInitialized() {
         memoizedIsInitialized = 0;
         return false;
       }
-      if (!hasAuthentication()) {
+      if (!hasPolicy()) {
         memoizedIsInitialized = 0;
         return false;
       }
@@ -207,7 +207,7 @@ public final boolean isInitialized() {
         memoizedIsInitialized = 0;
         return false;
       }
-      if (!getAuthentication().isInitialized()) {
+      if (!getPolicy().isInitialized()) {
         memoizedIsInitialized = 0;
         return false;
       }
@@ -222,7 +222,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
         output.writeMessage(1, getRoster());
       }
       if (((bitField0_ & 0x00000002) != 0)) {
-        output.writeMessage(2, getAuthentication());
+        output.writeMessage(2, getPolicy());
       }
       unknownFields.writeTo(output);
     }
@@ -239,7 +239,7 @@ public int getSerializedSize() {
       }
       if (((bitField0_ & 0x00000002) != 0)) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(2, getAuthentication());
+          .computeMessageSize(2, getPolicy());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -261,10 +261,10 @@ public boolean equals(final java.lang.Object obj) {
         if (!getRoster()
             .equals(other.getRoster())) return false;
       }
-      if (hasAuthentication() != other.hasAuthentication()) return false;
-      if (hasAuthentication()) {
-        if (!getAuthentication()
-            .equals(other.getAuthentication())) return false;
+      if (hasPolicy() != other.hasPolicy()) return false;
+      if (hasPolicy()) {
+        if (!getPolicy()
+            .equals(other.getPolicy())) return false;
       }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
@@ -281,9 +281,9 @@ public int hashCode() {
         hash = (37 * hash) + ROSTER_FIELD_NUMBER;
         hash = (53 * hash) + getRoster().hashCode();
       }
-      if (hasAuthentication()) {
-        hash = (37 * hash) + AUTHENTICATION_FIELD_NUMBER;
-        hash = (53 * hash) + getAuthentication().hashCode();
+      if (hasPolicy()) {
+        hash = (37 * hash) + POLICY_FIELD_NUMBER;
+        hash = (53 * hash) + getPolicy().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
@@ -418,7 +418,7 @@ private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
           getRosterFieldBuilder();
-          getAuthenticationFieldBuilder();
+          getPolicyFieldBuilder();
         }
       }
       @java.lang.Override
@@ -430,10 +430,10 @@ public Builder clear() {
           rosterBuilder_.clear();
         }
         bitField0_ = (bitField0_ & ~0x00000001);
-        if (authenticationBuilder_ == null) {
-          authentication_ = null;
+        if (policyBuilder_ == null) {
+          policy_ = null;
         } else {
-          authenticationBuilder_.clear();
+          policyBuilder_.clear();
         }
         bitField0_ = (bitField0_ & ~0x00000002);
         return this;
@@ -473,10 +473,10 @@ public ch.epfl.dedis.lib.proto.OCS.CreateOCS buildPartial() {
           to_bitField0_ |= 0x00000001;
         }
         if (((from_bitField0_ & 0x00000002) != 0)) {
-          if (authenticationBuilder_ == null) {
-            result.authentication_ = authentication_;
+          if (policyBuilder_ == null) {
+            result.policy_ = policy_;
           } else {
-            result.authentication_ = authenticationBuilder_.build();
+            result.policy_ = policyBuilder_.build();
           }
           to_bitField0_ |= 0x00000002;
         }
@@ -532,8 +532,8 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.CreateOCS other) {
         if (other.hasRoster()) {
           mergeRoster(other.getRoster());
         }
-        if (other.hasAuthentication()) {
-          mergeAuthentication(other.getAuthentication());
+        if (other.hasPolicy()) {
+          mergePolicy(other.getPolicy());
         }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
@@ -545,13 +545,13 @@ public final boolean isInitialized() {
         if (!hasRoster()) {
           return false;
         }
-        if (!hasAuthentication()) {
+        if (!hasPolicy()) {
           return false;
         }
         if (!getRoster().isInitialized()) {
           return false;
         }
-        if (!getAuthentication().isInitialized()) {
+        if (!getPolicy().isInitialized()) {
           return false;
         }
         return true;
@@ -695,122 +695,122 @@ public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() {
         return rosterBuilder_;
       }
 
-      private ch.epfl.dedis.lib.proto.OCS.Auth authentication_;
+      private ch.epfl.dedis.lib.proto.OCS.Policy policy_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          ch.epfl.dedis.lib.proto.OCS.Auth, ch.epfl.dedis.lib.proto.OCS.Auth.Builder, ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder> authenticationBuilder_;
+          ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> policyBuilder_;
       /**
-       * required .ocs.Auth authentication = 2;
+       * required .ocs.Policy policy = 2;
        */
-      public boolean hasAuthentication() {
+      public boolean hasPolicy() {
         return ((bitField0_ & 0x00000002) != 0);
       }
       /**
-       * required .ocs.Auth authentication = 2;
+       * required .ocs.Policy policy = 2;
        */
-      public ch.epfl.dedis.lib.proto.OCS.Auth getAuthentication() {
-        if (authenticationBuilder_ == null) {
-          return authentication_ == null ? ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance() : authentication_;
+      public ch.epfl.dedis.lib.proto.OCS.Policy getPolicy() {
+        if (policyBuilder_ == null) {
+          return policy_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policy_;
         } else {
-          return authenticationBuilder_.getMessage();
+          return policyBuilder_.getMessage();
         }
       }
       /**
-       * required .ocs.Auth authentication = 2;
+       * required .ocs.Policy policy = 2;
        */
-      public Builder setAuthentication(ch.epfl.dedis.lib.proto.OCS.Auth value) {
-        if (authenticationBuilder_ == null) {
+      public Builder setPolicy(ch.epfl.dedis.lib.proto.OCS.Policy value) {
+        if (policyBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          authentication_ = value;
+          policy_ = value;
           onChanged();
         } else {
-          authenticationBuilder_.setMessage(value);
+          policyBuilder_.setMessage(value);
         }
         bitField0_ |= 0x00000002;
         return this;
       }
       /**
-       * required .ocs.Auth authentication = 2;
+       * required .ocs.Policy policy = 2;
        */
-      public Builder setAuthentication(
-          ch.epfl.dedis.lib.proto.OCS.Auth.Builder builderForValue) {
-        if (authenticationBuilder_ == null) {
-          authentication_ = builderForValue.build();
+      public Builder setPolicy(
+          ch.epfl.dedis.lib.proto.OCS.Policy.Builder builderForValue) {
+        if (policyBuilder_ == null) {
+          policy_ = builderForValue.build();
           onChanged();
         } else {
-          authenticationBuilder_.setMessage(builderForValue.build());
+          policyBuilder_.setMessage(builderForValue.build());
         }
         bitField0_ |= 0x00000002;
         return this;
       }
       /**
-       * required .ocs.Auth authentication = 2;
+       * required .ocs.Policy policy = 2;
        */
-      public Builder mergeAuthentication(ch.epfl.dedis.lib.proto.OCS.Auth value) {
-        if (authenticationBuilder_ == null) {
+      public Builder mergePolicy(ch.epfl.dedis.lib.proto.OCS.Policy value) {
+        if (policyBuilder_ == null) {
           if (((bitField0_ & 0x00000002) != 0) &&
-              authentication_ != null &&
-              authentication_ != ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance()) {
-            authentication_ =
-              ch.epfl.dedis.lib.proto.OCS.Auth.newBuilder(authentication_).mergeFrom(value).buildPartial();
+              policy_ != null &&
+              policy_ != ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) {
+            policy_ =
+              ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder(policy_).mergeFrom(value).buildPartial();
           } else {
-            authentication_ = value;
+            policy_ = value;
           }
           onChanged();
         } else {
-          authenticationBuilder_.mergeFrom(value);
+          policyBuilder_.mergeFrom(value);
         }
         bitField0_ |= 0x00000002;
         return this;
       }
       /**
-       * required .ocs.Auth authentication = 2;
+       * required .ocs.Policy policy = 2;
        */
-      public Builder clearAuthentication() {
-        if (authenticationBuilder_ == null) {
-          authentication_ = null;
+      public Builder clearPolicy() {
+        if (policyBuilder_ == null) {
+          policy_ = null;
           onChanged();
         } else {
-          authenticationBuilder_.clear();
+          policyBuilder_.clear();
         }
         bitField0_ = (bitField0_ & ~0x00000002);
         return this;
       }
       /**
-       * required .ocs.Auth authentication = 2;
+       * required .ocs.Policy policy = 2;
        */
-      public ch.epfl.dedis.lib.proto.OCS.Auth.Builder getAuthenticationBuilder() {
+      public ch.epfl.dedis.lib.proto.OCS.Policy.Builder getPolicyBuilder() {
         bitField0_ |= 0x00000002;
         onChanged();
-        return getAuthenticationFieldBuilder().getBuilder();
+        return getPolicyFieldBuilder().getBuilder();
       }
       /**
-       * required .ocs.Auth authentication = 2;
+       * required .ocs.Policy policy = 2;
        */
-      public ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder getAuthenticationOrBuilder() {
-        if (authenticationBuilder_ != null) {
-          return authenticationBuilder_.getMessageOrBuilder();
+      public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyOrBuilder() {
+        if (policyBuilder_ != null) {
+          return policyBuilder_.getMessageOrBuilder();
         } else {
-          return authentication_ == null ?
-              ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance() : authentication_;
+          return policy_ == null ?
+              ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policy_;
         }
       }
       /**
-       * required .ocs.Auth authentication = 2;
+       * required .ocs.Policy policy = 2;
        */
       private com.google.protobuf.SingleFieldBuilderV3<
-          ch.epfl.dedis.lib.proto.OCS.Auth, ch.epfl.dedis.lib.proto.OCS.Auth.Builder, ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder> 
-          getAuthenticationFieldBuilder() {
-        if (authenticationBuilder_ == null) {
-          authenticationBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              ch.epfl.dedis.lib.proto.OCS.Auth, ch.epfl.dedis.lib.proto.OCS.Auth.Builder, ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder>(
-                  getAuthentication(),
+          ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> 
+          getPolicyFieldBuilder() {
+        if (policyBuilder_ == null) {
+          policyBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder>(
+                  getPolicy(),
                   getParentForChildren(),
                   isClean());
-          authentication_ = null;
+          policy_ = null;
         }
-        return authenticationBuilder_;
+        return policyBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -1506,22 +1506,22 @@ public interface ReencryptOrBuilder extends
     com.google.protobuf.ByteString getX();
 
     /**
-     * required .ocs.Grant grant = 2;
+     * required .ocs.AuthReencrypt auth = 2;
      */
-    boolean hasGrant();
+    boolean hasAuth();
     /**
-     * required .ocs.Grant grant = 2;
+     * required .ocs.AuthReencrypt auth = 2;
      */
-    ch.epfl.dedis.lib.proto.OCS.Grant getGrant();
+    ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getAuth();
     /**
-     * required .ocs.Grant grant = 2;
+     * required .ocs.AuthReencrypt auth = 2;
      */
-    ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder getGrantOrBuilder();
+    ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder getAuthOrBuilder();
   }
   /**
    * 
    * Reencrypt is sent to the service to request a re-encryption of the
-   * secret given in Grant. Grant must also contain the proof that the
+   * secret given in AuthReencrypt. AuthReencrypt must also contain the proof that the
    * request is valid, as well as the ephemeral key, to which the secret
    * will be re-encrypted.
    * 
@@ -1571,14 +1571,14 @@ private Reencrypt( break; } case 18: { - ch.epfl.dedis.lib.proto.OCS.Grant.Builder subBuilder = null; + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder subBuilder = null; if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = grant_.toBuilder(); + subBuilder = auth_.toBuilder(); } - grant_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Grant.parser(), extensionRegistry); + auth_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.parser(), extensionRegistry); if (subBuilder != null) { - subBuilder.mergeFrom(grant_); - grant_ = subBuilder.buildPartial(); + subBuilder.mergeFrom(auth_); + auth_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000002; break; @@ -1631,25 +1631,25 @@ public com.google.protobuf.ByteString getX() { return x_; } - public static final int GRANT_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.OCS.Grant grant_; + public static final int AUTH_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.AuthReencrypt auth_; /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ - public boolean hasGrant() { + public boolean hasAuth() { return ((bitField0_ & 0x00000002) != 0); } /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ - public ch.epfl.dedis.lib.proto.OCS.Grant getGrant() { - return grant_ == null ? ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance() : grant_; + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getAuth() { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; } /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ - public ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder getGrantOrBuilder() { - return grant_ == null ? ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance() : grant_; + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder getAuthOrBuilder() { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; } private byte memoizedIsInitialized = -1; @@ -1663,11 +1663,11 @@ public final boolean isInitialized() { memoizedIsInitialized = 0; return false; } - if (!hasGrant()) { + if (!hasAuth()) { memoizedIsInitialized = 0; return false; } - if (!getGrant().isInitialized()) { + if (!getAuth().isInitialized()) { memoizedIsInitialized = 0; return false; } @@ -1682,7 +1682,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) output.writeBytes(1, x_); } if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getGrant()); + output.writeMessage(2, getAuth()); } unknownFields.writeTo(output); } @@ -1699,7 +1699,7 @@ public int getSerializedSize() { } if (((bitField0_ & 0x00000002) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getGrant()); + .computeMessageSize(2, getAuth()); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -1721,10 +1721,10 @@ public boolean equals(final java.lang.Object obj) { if (!getX() .equals(other.getX())) return false; } - if (hasGrant() != other.hasGrant()) return false; - if (hasGrant()) { - if (!getGrant() - .equals(other.getGrant())) return false; + if (hasAuth() != other.hasAuth()) return false; + if (hasAuth()) { + if (!getAuth() + .equals(other.getAuth())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -1741,9 +1741,9 @@ public int hashCode() { hash = (37 * hash) + X_FIELD_NUMBER; hash = (53 * hash) + getX().hashCode(); } - if (hasGrant()) { - hash = (37 * hash) + GRANT_FIELD_NUMBER; - hash = (53 * hash) + getGrant().hashCode(); + if (hasAuth()) { + hash = (37 * hash) + AUTH_FIELD_NUMBER; + hash = (53 * hash) + getAuth().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; @@ -1843,7 +1843,7 @@ protected Builder newBuilderForType( /** *
      * Reencrypt is sent to the service to request a re-encryption of the
-     * secret given in Grant. Grant must also contain the proof that the
+     * secret given in AuthReencrypt. AuthReencrypt must also contain the proof that the
      * request is valid, as well as the ephemeral key, to which the secret
      * will be re-encrypted.
      * 
@@ -1880,7 +1880,7 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { - getGrantFieldBuilder(); + getAuthFieldBuilder(); } } @java.lang.Override @@ -1888,10 +1888,10 @@ public Builder clear() { super.clear(); x_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); - if (grantBuilder_ == null) { - grant_ = null; + if (authBuilder_ == null) { + auth_ = null; } else { - grantBuilder_.clear(); + authBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000002); return this; @@ -1927,10 +1927,10 @@ public ch.epfl.dedis.lib.proto.OCS.Reencrypt buildPartial() { } result.x_ = x_; if (((from_bitField0_ & 0x00000002) != 0)) { - if (grantBuilder_ == null) { - result.grant_ = grant_; + if (authBuilder_ == null) { + result.auth_ = auth_; } else { - result.grant_ = grantBuilder_.build(); + result.auth_ = authBuilder_.build(); } to_bitField0_ |= 0x00000002; } @@ -1986,8 +1986,8 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Reencrypt other) { if (other.hasX()) { setX(other.getX()); } - if (other.hasGrant()) { - mergeGrant(other.getGrant()); + if (other.hasAuth()) { + mergeAuth(other.getAuth()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -1999,10 +1999,10 @@ public final boolean isInitialized() { if (!hasX()) { return false; } - if (!hasGrant()) { + if (!hasAuth()) { return false; } - if (!getGrant().isInitialized()) { + if (!getAuth().isInitialized()) { return false; } return true; @@ -2063,122 +2063,122 @@ public Builder clearX() { return this; } - private ch.epfl.dedis.lib.proto.OCS.Grant grant_; + private ch.epfl.dedis.lib.proto.OCS.AuthReencrypt auth_; private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Grant, ch.epfl.dedis.lib.proto.OCS.Grant.Builder, ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder> grantBuilder_; + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder> authBuilder_; /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ - public boolean hasGrant() { + public boolean hasAuth() { return ((bitField0_ & 0x00000002) != 0); } /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ - public ch.epfl.dedis.lib.proto.OCS.Grant getGrant() { - if (grantBuilder_ == null) { - return grant_ == null ? ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance() : grant_; + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getAuth() { + if (authBuilder_ == null) { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; } else { - return grantBuilder_.getMessage(); + return authBuilder_.getMessage(); } } /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ - public Builder setGrant(ch.epfl.dedis.lib.proto.OCS.Grant value) { - if (grantBuilder_ == null) { + public Builder setAuth(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt value) { + if (authBuilder_ == null) { if (value == null) { throw new NullPointerException(); } - grant_ = value; + auth_ = value; onChanged(); } else { - grantBuilder_.setMessage(value); + authBuilder_.setMessage(value); } bitField0_ |= 0x00000002; return this; } /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ - public Builder setGrant( - ch.epfl.dedis.lib.proto.OCS.Grant.Builder builderForValue) { - if (grantBuilder_ == null) { - grant_ = builderForValue.build(); + public Builder setAuth( + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder builderForValue) { + if (authBuilder_ == null) { + auth_ = builderForValue.build(); onChanged(); } else { - grantBuilder_.setMessage(builderForValue.build()); + authBuilder_.setMessage(builderForValue.build()); } bitField0_ |= 0x00000002; return this; } /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ - public Builder mergeGrant(ch.epfl.dedis.lib.proto.OCS.Grant value) { - if (grantBuilder_ == null) { + public Builder mergeAuth(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt value) { + if (authBuilder_ == null) { if (((bitField0_ & 0x00000002) != 0) && - grant_ != null && - grant_ != ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance()) { - grant_ = - ch.epfl.dedis.lib.proto.OCS.Grant.newBuilder(grant_).mergeFrom(value).buildPartial(); + auth_ != null && + auth_ != ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance()) { + auth_ = + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.newBuilder(auth_).mergeFrom(value).buildPartial(); } else { - grant_ = value; + auth_ = value; } onChanged(); } else { - grantBuilder_.mergeFrom(value); + authBuilder_.mergeFrom(value); } bitField0_ |= 0x00000002; return this; } /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ - public Builder clearGrant() { - if (grantBuilder_ == null) { - grant_ = null; + public Builder clearAuth() { + if (authBuilder_ == null) { + auth_ = null; onChanged(); } else { - grantBuilder_.clear(); + authBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000002); return this; } /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ - public ch.epfl.dedis.lib.proto.OCS.Grant.Builder getGrantBuilder() { + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder getAuthBuilder() { bitField0_ |= 0x00000002; onChanged(); - return getGrantFieldBuilder().getBuilder(); + return getAuthFieldBuilder().getBuilder(); } /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ - public ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder getGrantOrBuilder() { - if (grantBuilder_ != null) { - return grantBuilder_.getMessageOrBuilder(); + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder getAuthOrBuilder() { + if (authBuilder_ != null) { + return authBuilder_.getMessageOrBuilder(); } else { - return grant_ == null ? - ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance() : grant_; + return auth_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; } } /** - * required .ocs.Grant grant = 2; + * required .ocs.AuthReencrypt auth = 2; */ private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Grant, ch.epfl.dedis.lib.proto.OCS.Grant.Builder, ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder> - getGrantFieldBuilder() { - if (grantBuilder_ == null) { - grantBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Grant, ch.epfl.dedis.lib.proto.OCS.Grant.Builder, ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder>( - getGrant(), + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder> + getAuthFieldBuilder() { + if (authBuilder_ == null) { + authBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder>( + getAuth(), getParentForChildren(), isClean()); - grant_ = null; + auth_ = null; } - return grantBuilder_; + return authBuilder_; } @java.lang.Override public final Builder setUnknownFields( @@ -2248,9 +2248,9 @@ public interface ReencryptReplyOrBuilder extends } /** *
-   * ReencryptReply is the reply if the re-encryption is successful, and
+   * MessageReencryptReply is the reply if the re-encryption is successful, and
    * it contains XHat, which is the secret re-encrypted to the ephemeral
-   * key given in Grant.
+   * key given in AuthReencrypt.
    * 
* * Protobuf type {@code ocs.ReencryptReply} @@ -2511,9 +2511,9 @@ protected Builder newBuilderForType( } /** *
-     * ReencryptReply is the reply if the re-encryption is successful, and
+     * MessageReencryptReply is the reply if the re-encryption is successful, and
      * it contains XHat, which is the secret re-encrypted to the ephemeral
-     * key given in Grant.
+     * key given in AuthReencrypt.
      * 
* * Protobuf type {@code ocs.ReencryptReply} @@ -2759,54 +2759,65 @@ public ch.epfl.dedis.lib.proto.OCS.ReencryptReply getDefaultInstanceForType() { } - public interface AuthOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.Auth) + public interface ReshareOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.Reshare) com.google.protobuf.MessageOrBuilder { /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required bytes x = 1; */ - boolean hasByzcoin(); + boolean hasX(); + /** + * required bytes x = 1; + */ + com.google.protobuf.ByteString getX(); + /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required .onet.Roster newroster = 2; */ - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getByzcoin(); + boolean hasNewroster(); /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required .onet.Roster newroster = 2; */ - ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder getByzcoinOrBuilder(); + ch.epfl.dedis.lib.proto.OnetProto.Roster getNewroster(); + /** + * required .onet.Roster newroster = 2; + */ + ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getNewrosterOrBuilder(); /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - boolean hasAuthx509Cert(); + boolean hasAuth(); /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getAuthx509Cert(); + ch.epfl.dedis.lib.proto.OCS.AuthReshare getAuth(); /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder getAuthx509CertOrBuilder(); + ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder getAuthOrBuilder(); } /** *
-   * Auth holds all possible authentication structures. When using it to call
-   * Authorise, only one of the fields must be non-nil.
+   * Reshare is called to ask OCS to change the roster. It needs a valid
+   * authentication before the private keys are re-generated over the new
+   * roster.
    * 
* - * Protobuf type {@code ocs.Auth} + * Protobuf type {@code ocs.Reshare} */ - public static final class Auth extends + public static final class Reshare extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.Auth) - AuthOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.Reshare) + ReshareOrBuilder { private static final long serialVersionUID = 0L; - // Use Auth.newBuilder() to construct. - private Auth(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use Reshare.newBuilder() to construct. + private Reshare(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private Auth() { + private Reshare() { + x_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -2814,7 +2825,7 @@ private Auth() { getUnknownFields() { return this.unknownFields; } - private Auth( + private Reshare( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -2834,31 +2845,36 @@ private Auth( done = true; break; case 10: { - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder subBuilder = null; - if (((bitField0_ & 0x00000001) != 0)) { - subBuilder = byzcoin_.toBuilder(); - } - byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(byzcoin_); - byzcoin_ = subBuilder.buildPartial(); - } bitField0_ |= 0x00000001; + x_ = input.readBytes(); break; } case 18: { - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder subBuilder = null; + ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null; if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = authx509Cert_.toBuilder(); + subBuilder = newroster_.toBuilder(); } - authx509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.parser(), extensionRegistry); + newroster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry); if (subBuilder != null) { - subBuilder.mergeFrom(authx509Cert_); - authx509Cert_ = subBuilder.buildPartial(); + subBuilder.mergeFrom(newroster_); + newroster_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000002; break; } + case 26: { + ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder subBuilder = null; + if (((bitField0_ & 0x00000004) != 0)) { + subBuilder = auth_.toBuilder(); + } + auth_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReshare.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(auth_); + auth_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000004; + break; + } default: { if (!parseUnknownField( input, unknownFields, extensionRegistry, tag)) { @@ -2880,58 +2896,73 @@ private Auth( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Auth_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Auth_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.Auth.class, ch.epfl.dedis.lib.proto.OCS.Auth.Builder.class); + ch.epfl.dedis.lib.proto.OCS.Reshare.class, ch.epfl.dedis.lib.proto.OCS.Reshare.Builder.class); } private int bitField0_; - public static final int BYZCOIN_FIELD_NUMBER = 1; - private ch.epfl.dedis.lib.proto.OCS.AuthByzCoin byzcoin_; + public static final int X_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString x_; /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required bytes x = 1; */ - public boolean hasByzcoin() { + public boolean hasX() { return ((bitField0_ & 0x00000001) != 0); } /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required bytes x = 1; + */ + public com.google.protobuf.ByteString getX() { + return x_; + } + + public static final int NEWROSTER_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OnetProto.Roster newroster_; + /** + * required .onet.Roster newroster = 2; + */ + public boolean hasNewroster() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .onet.Roster newroster = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getByzcoin() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance() : byzcoin_; + public ch.epfl.dedis.lib.proto.OnetProto.Roster getNewroster() { + return newroster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; } /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required .onet.Roster newroster = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder getByzcoinOrBuilder() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance() : byzcoin_; + public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getNewrosterOrBuilder() { + return newroster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; } - public static final int AUTHX509CERT_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.OCS.AuthX509Cert authx509Cert_; + public static final int AUTH_FIELD_NUMBER = 3; + private ch.epfl.dedis.lib.proto.OCS.AuthReshare auth_; /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - public boolean hasAuthx509Cert() { - return ((bitField0_ & 0x00000002) != 0); + public boolean hasAuth() { + return ((bitField0_ & 0x00000004) != 0); } /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getAuthx509Cert() { - return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance() : authx509Cert_; + public ch.epfl.dedis.lib.proto.OCS.AuthReshare getAuth() { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; } /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - public ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder getAuthx509CertOrBuilder() { - return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance() : authx509Cert_; + public ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder getAuthOrBuilder() { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; } private byte memoizedIsInitialized = -1; @@ -2941,17 +2972,25 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } + if (!hasX()) { + memoizedIsInitialized = 0; + return false; } - if (hasAuthx509Cert()) { - if (!getAuthx509Cert().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } + if (!hasNewroster()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasAuth()) { + memoizedIsInitialized = 0; + return false; + } + if (!getNewroster().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getAuth().isInitialized()) { + memoizedIsInitialized = 0; + return false; } memoizedIsInitialized = 1; return true; @@ -2961,10 +3000,13 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeMessage(1, getByzcoin()); + output.writeBytes(1, x_); } if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getAuthx509Cert()); + output.writeMessage(2, getNewroster()); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeMessage(3, getAuth()); } unknownFields.writeTo(output); } @@ -2977,11 +3019,15 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, getByzcoin()); + .computeBytesSize(1, x_); } if (((bitField0_ & 0x00000002) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getAuthx509Cert()); + .computeMessageSize(2, getNewroster()); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, getAuth()); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -2993,20 +3039,25 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Auth)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Reshare)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.Auth other = (ch.epfl.dedis.lib.proto.OCS.Auth) obj; + ch.epfl.dedis.lib.proto.OCS.Reshare other = (ch.epfl.dedis.lib.proto.OCS.Reshare) obj; - if (hasByzcoin() != other.hasByzcoin()) return false; - if (hasByzcoin()) { - if (!getByzcoin() - .equals(other.getByzcoin())) return false; + if (hasX() != other.hasX()) return false; + if (hasX()) { + if (!getX() + .equals(other.getX())) return false; } - if (hasAuthx509Cert() != other.hasAuthx509Cert()) return false; - if (hasAuthx509Cert()) { - if (!getAuthx509Cert() - .equals(other.getAuthx509Cert())) return false; + if (hasNewroster() != other.hasNewroster()) return false; + if (hasNewroster()) { + if (!getNewroster() + .equals(other.getNewroster())) return false; + } + if (hasAuth() != other.hasAuth()) return false; + if (hasAuth()) { + if (!getAuth() + .equals(other.getAuth())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -3019,82 +3070,86 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasByzcoin()) { - hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; - hash = (53 * hash) + getByzcoin().hashCode(); + if (hasX()) { + hash = (37 * hash) + X_FIELD_NUMBER; + hash = (53 * hash) + getX().hashCode(); } - if (hasAuthx509Cert()) { - hash = (37 * hash) + AUTHX509CERT_FIELD_NUMBER; - hash = (53 * hash) + getAuthx509Cert().hashCode(); + if (hasNewroster()) { + hash = (37 * hash) + NEWROSTER_FIELD_NUMBER; + hash = (53 * hash) + getNewroster().hashCode(); + } + if (hasAuth()) { + hash = (37 * hash) + AUTH_FIELD_NUMBER; + hash = (53 * hash) + getAuth().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3107,7 +3162,7 @@ public static ch.epfl.dedis.lib.proto.OCS.Auth parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Auth prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Reshare prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -3124,30 +3179,31 @@ protected Builder newBuilderForType( } /** *
-     * Auth holds all possible authentication structures. When using it to call
-     * Authorise, only one of the fields must be non-nil.
+     * Reshare is called to ask OCS to change the roster. It needs a valid
+     * authentication before the private keys are re-generated over the new
+     * roster.
      * 
* - * Protobuf type {@code ocs.Auth} + * Protobuf type {@code ocs.Reshare} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.Auth) - ch.epfl.dedis.lib.proto.OCS.AuthOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.Reshare) + ch.epfl.dedis.lib.proto.OCS.ReshareOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Auth_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Auth_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.Auth.class, ch.epfl.dedis.lib.proto.OCS.Auth.Builder.class); + ch.epfl.dedis.lib.proto.OCS.Reshare.class, ch.epfl.dedis.lib.proto.OCS.Reshare.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.Auth.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.Reshare.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -3160,42 +3216,44 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { - getByzcoinFieldBuilder(); - getAuthx509CertFieldBuilder(); + getNewrosterFieldBuilder(); + getAuthFieldBuilder(); } } @java.lang.Override public Builder clear() { super.clear(); - if (byzcoinBuilder_ == null) { - byzcoin_ = null; - } else { - byzcoinBuilder_.clear(); - } + x_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); - if (authx509CertBuilder_ == null) { - authx509Cert_ = null; + if (newrosterBuilder_ == null) { + newroster_ = null; } else { - authx509CertBuilder_.clear(); + newrosterBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000002); + if (authBuilder_ == null) { + auth_ = null; + } else { + authBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Auth_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Auth getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.Reshare getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.Reshare.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Auth build() { - ch.epfl.dedis.lib.proto.OCS.Auth result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.Reshare build() { + ch.epfl.dedis.lib.proto.OCS.Reshare result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -3203,26 +3261,30 @@ public ch.epfl.dedis.lib.proto.OCS.Auth build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Auth buildPartial() { - ch.epfl.dedis.lib.proto.OCS.Auth result = new ch.epfl.dedis.lib.proto.OCS.Auth(this); + public ch.epfl.dedis.lib.proto.OCS.Reshare buildPartial() { + ch.epfl.dedis.lib.proto.OCS.Reshare result = new ch.epfl.dedis.lib.proto.OCS.Reshare(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { - if (byzcoinBuilder_ == null) { - result.byzcoin_ = byzcoin_; - } else { - result.byzcoin_ = byzcoinBuilder_.build(); - } to_bitField0_ |= 0x00000001; } + result.x_ = x_; if (((from_bitField0_ & 0x00000002) != 0)) { - if (authx509CertBuilder_ == null) { - result.authx509Cert_ = authx509Cert_; + if (newrosterBuilder_ == null) { + result.newroster_ = newroster_; } else { - result.authx509Cert_ = authx509CertBuilder_.build(); + result.newroster_ = newrosterBuilder_.build(); } to_bitField0_ |= 0x00000002; } + if (((from_bitField0_ & 0x00000004) != 0)) { + if (authBuilder_ == null) { + result.auth_ = auth_; + } else { + result.auth_ = authBuilder_.build(); + } + to_bitField0_ |= 0x00000004; + } result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -3262,21 +3324,24 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.Auth) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Auth)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.Reshare) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Reshare)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Auth other) { - if (other == ch.epfl.dedis.lib.proto.OCS.Auth.getDefaultInstance()) return this; - if (other.hasByzcoin()) { - mergeByzcoin(other.getByzcoin()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Reshare other) { + if (other == ch.epfl.dedis.lib.proto.OCS.Reshare.getDefaultInstance()) return this; + if (other.hasX()) { + setX(other.getX()); } - if (other.hasAuthx509Cert()) { - mergeAuthx509Cert(other.getAuthx509Cert()); + if (other.hasNewroster()) { + mergeNewroster(other.getNewroster()); + } + if (other.hasAuth()) { + mergeAuth(other.getAuth()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -3285,15 +3350,20 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Auth other) { @java.lang.Override public final boolean isInitialized() { - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - return false; - } + if (!hasX()) { + return false; } - if (hasAuthx509Cert()) { - if (!getAuthx509Cert().isInitialized()) { - return false; - } + if (!hasNewroster()) { + return false; + } + if (!hasAuth()) { + return false; + } + if (!getNewroster().isInitialized()) { + return false; + } + if (!getAuth().isInitialized()) { + return false; } return true; } @@ -3303,11 +3373,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.Auth parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.Reshare parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Auth) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Reshare) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -3318,240 +3388,275 @@ public Builder mergeFrom( } private int bitField0_; - private ch.epfl.dedis.lib.proto.OCS.AuthByzCoin byzcoin_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder> byzcoinBuilder_; + private com.google.protobuf.ByteString x_ = com.google.protobuf.ByteString.EMPTY; /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required bytes x = 1; */ - public boolean hasByzcoin() { + public boolean hasX() { return ((bitField0_ & 0x00000001) != 0); } /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required bytes x = 1; */ - public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getByzcoin() { - if (byzcoinBuilder_ == null) { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance() : byzcoin_; + public com.google.protobuf.ByteString getX() { + return x_; + } + /** + * required bytes x = 1; + */ + public Builder setX(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + x_ = value; + onChanged(); + return this; + } + /** + * required bytes x = 1; + */ + public Builder clearX() { + bitField0_ = (bitField0_ & ~0x00000001); + x_ = getDefaultInstance().getX(); + onChanged(); + return this; + } + + private ch.epfl.dedis.lib.proto.OnetProto.Roster newroster_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> newrosterBuilder_; + /** + * required .onet.Roster newroster = 2; + */ + public boolean hasNewroster() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .onet.Roster newroster = 2; + */ + public ch.epfl.dedis.lib.proto.OnetProto.Roster getNewroster() { + if (newrosterBuilder_ == null) { + return newroster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; } else { - return byzcoinBuilder_.getMessage(); + return newrosterBuilder_.getMessage(); } } /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required .onet.Roster newroster = 2; */ - public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthByzCoin value) { - if (byzcoinBuilder_ == null) { + public Builder setNewroster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { + if (newrosterBuilder_ == null) { if (value == null) { throw new NullPointerException(); } - byzcoin_ = value; + newroster_ = value; onChanged(); } else { - byzcoinBuilder_.setMessage(value); + newrosterBuilder_.setMessage(value); } - bitField0_ |= 0x00000001; + bitField0_ |= 0x00000002; return this; } /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required .onet.Roster newroster = 2; */ - public Builder setByzcoin( - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder builderForValue) { - if (byzcoinBuilder_ == null) { - byzcoin_ = builderForValue.build(); + public Builder setNewroster( + ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder builderForValue) { + if (newrosterBuilder_ == null) { + newroster_ = builderForValue.build(); onChanged(); } else { - byzcoinBuilder_.setMessage(builderForValue.build()); + newrosterBuilder_.setMessage(builderForValue.build()); } - bitField0_ |= 0x00000001; + bitField0_ |= 0x00000002; return this; } /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required .onet.Roster newroster = 2; */ - public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthByzCoin value) { - if (byzcoinBuilder_ == null) { - if (((bitField0_ & 0x00000001) != 0) && - byzcoin_ != null && - byzcoin_ != ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance()) { - byzcoin_ = - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); + public Builder mergeNewroster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { + if (newrosterBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + newroster_ != null && + newroster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) { + newroster_ = + ch.epfl.dedis.lib.proto.OnetProto.Roster.newBuilder(newroster_).mergeFrom(value).buildPartial(); } else { - byzcoin_ = value; + newroster_ = value; } onChanged(); } else { - byzcoinBuilder_.mergeFrom(value); + newrosterBuilder_.mergeFrom(value); } - bitField0_ |= 0x00000001; + bitField0_ |= 0x00000002; return this; } /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required .onet.Roster newroster = 2; */ - public Builder clearByzcoin() { - if (byzcoinBuilder_ == null) { - byzcoin_ = null; + public Builder clearNewroster() { + if (newrosterBuilder_ == null) { + newroster_ = null; onChanged(); } else { - byzcoinBuilder_.clear(); + newrosterBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00000001); + bitField0_ = (bitField0_ & ~0x00000002); return this; } /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required .onet.Roster newroster = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder getByzcoinBuilder() { - bitField0_ |= 0x00000001; + public ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder getNewrosterBuilder() { + bitField0_ |= 0x00000002; onChanged(); - return getByzcoinFieldBuilder().getBuilder(); + return getNewrosterFieldBuilder().getBuilder(); } /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required .onet.Roster newroster = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder getByzcoinOrBuilder() { - if (byzcoinBuilder_ != null) { - return byzcoinBuilder_.getMessageOrBuilder(); + public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getNewrosterOrBuilder() { + if (newrosterBuilder_ != null) { + return newrosterBuilder_.getMessageOrBuilder(); } else { - return byzcoin_ == null ? - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance() : byzcoin_; + return newroster_ == null ? + ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; } } /** - * optional .ocs.AuthByzCoin byzcoin = 1; + * required .onet.Roster newroster = 2; */ private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder> - getByzcoinFieldBuilder() { - if (byzcoinBuilder_ == null) { - byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder>( - getByzcoin(), + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> + getNewrosterFieldBuilder() { + if (newrosterBuilder_ == null) { + newrosterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder>( + getNewroster(), getParentForChildren(), isClean()); - byzcoin_ = null; + newroster_ = null; } - return byzcoinBuilder_; + return newrosterBuilder_; } - private ch.epfl.dedis.lib.proto.OCS.AuthX509Cert authx509Cert_; + private ch.epfl.dedis.lib.proto.OCS.AuthReshare auth_; private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder> authx509CertBuilder_; + ch.epfl.dedis.lib.proto.OCS.AuthReshare, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder> authBuilder_; /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - public boolean hasAuthx509Cert() { - return ((bitField0_ & 0x00000002) != 0); + public boolean hasAuth() { + return ((bitField0_ & 0x00000004) != 0); } /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getAuthx509Cert() { - if (authx509CertBuilder_ == null) { - return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance() : authx509Cert_; + public ch.epfl.dedis.lib.proto.OCS.AuthReshare getAuth() { + if (authBuilder_ == null) { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; } else { - return authx509CertBuilder_.getMessage(); + return authBuilder_.getMessage(); } } /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - public Builder setAuthx509Cert(ch.epfl.dedis.lib.proto.OCS.AuthX509Cert value) { - if (authx509CertBuilder_ == null) { + public Builder setAuth(ch.epfl.dedis.lib.proto.OCS.AuthReshare value) { + if (authBuilder_ == null) { if (value == null) { throw new NullPointerException(); } - authx509Cert_ = value; + auth_ = value; onChanged(); } else { - authx509CertBuilder_.setMessage(value); + authBuilder_.setMessage(value); } - bitField0_ |= 0x00000002; + bitField0_ |= 0x00000004; return this; } /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - public Builder setAuthx509Cert( - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder builderForValue) { - if (authx509CertBuilder_ == null) { - authx509Cert_ = builderForValue.build(); + public Builder setAuth( + ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder builderForValue) { + if (authBuilder_ == null) { + auth_ = builderForValue.build(); onChanged(); } else { - authx509CertBuilder_.setMessage(builderForValue.build()); + authBuilder_.setMessage(builderForValue.build()); } - bitField0_ |= 0x00000002; + bitField0_ |= 0x00000004; return this; } /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - public Builder mergeAuthx509Cert(ch.epfl.dedis.lib.proto.OCS.AuthX509Cert value) { - if (authx509CertBuilder_ == null) { - if (((bitField0_ & 0x00000002) != 0) && - authx509Cert_ != null && - authx509Cert_ != ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance()) { - authx509Cert_ = - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.newBuilder(authx509Cert_).mergeFrom(value).buildPartial(); + public Builder mergeAuth(ch.epfl.dedis.lib.proto.OCS.AuthReshare value) { + if (authBuilder_ == null) { + if (((bitField0_ & 0x00000004) != 0) && + auth_ != null && + auth_ != ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance()) { + auth_ = + ch.epfl.dedis.lib.proto.OCS.AuthReshare.newBuilder(auth_).mergeFrom(value).buildPartial(); } else { - authx509Cert_ = value; + auth_ = value; } onChanged(); } else { - authx509CertBuilder_.mergeFrom(value); + authBuilder_.mergeFrom(value); } - bitField0_ |= 0x00000002; + bitField0_ |= 0x00000004; return this; } /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - public Builder clearAuthx509Cert() { - if (authx509CertBuilder_ == null) { - authx509Cert_ = null; + public Builder clearAuth() { + if (authBuilder_ == null) { + auth_ = null; onChanged(); } else { - authx509CertBuilder_.clear(); + authBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00000002); + bitField0_ = (bitField0_ & ~0x00000004); return this; } /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder getAuthx509CertBuilder() { - bitField0_ |= 0x00000002; + public ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder getAuthBuilder() { + bitField0_ |= 0x00000004; onChanged(); - return getAuthx509CertFieldBuilder().getBuilder(); + return getAuthFieldBuilder().getBuilder(); } /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ - public ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder getAuthx509CertOrBuilder() { - if (authx509CertBuilder_ != null) { - return authx509CertBuilder_.getMessageOrBuilder(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder getAuthOrBuilder() { + if (authBuilder_ != null) { + return authBuilder_.getMessageOrBuilder(); } else { - return authx509Cert_ == null ? - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance() : authx509Cert_; + return auth_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; } } /** - * optional .ocs.AuthX509Cert authx509cert = 2; + * required .ocs.AuthReshare auth = 3; */ private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder> - getAuthx509CertFieldBuilder() { - if (authx509CertBuilder_ == null) { - authx509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder>( - getAuthx509Cert(), + ch.epfl.dedis.lib.proto.OCS.AuthReshare, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder> + getAuthFieldBuilder() { + if (authBuilder_ == null) { + authBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReshare, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder>( + getAuth(), getParentForChildren(), isClean()); - authx509Cert_ = null; + auth_ = null; } - return authx509CertBuilder_; + return authBuilder_; } @java.lang.Override public final Builder setUnknownFields( @@ -3566,89 +3671,79 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.Auth) + // @@protoc_insertion_point(builder_scope:ocs.Reshare) } - // @@protoc_insertion_point(class_scope:ocs.Auth) - private static final ch.epfl.dedis.lib.proto.OCS.Auth DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.Reshare) + private static final ch.epfl.dedis.lib.proto.OCS.Reshare DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Auth(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Reshare(); } - public static ch.epfl.dedis.lib.proto.OCS.Auth getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.Reshare getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public Auth parsePartialFrom( + public Reshare parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new Auth(input, extensionRegistry); + return new Reshare(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Auth getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.Reshare getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface AuthByzCoinOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.AuthByzCoin) + public interface ReshareReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.ReshareReply) com.google.protobuf.MessageOrBuilder { /** - * required bytes byzcoinid = 1; - */ - boolean hasByzcoinid(); - /** - * required bytes byzcoinid = 1; - */ - com.google.protobuf.ByteString getByzcoinid(); - - /** - * required uint64 ttl = 2; + * required bytes sig = 1; */ - boolean hasTtl(); + boolean hasSig(); /** - * required uint64 ttl = 2; + * required bytes sig = 1; */ - long getTtl(); + com.google.protobuf.ByteString getSig(); } /** *
-   * AuthByzCoin holds the information necessary to authenticate a byzcoin request.
-   * In the ByzCoin model, all requests are valid as long as they are stored in the
-   * blockchain with the given ID.
-   * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+   * ReshareReply is returned if the resharing has been completed successfully
+   * and contains the collective signature on the message
+   *   sha256( X | NewRoster )
    * 
* - * Protobuf type {@code ocs.AuthByzCoin} + * Protobuf type {@code ocs.ReshareReply} */ - public static final class AuthByzCoin extends + public static final class ReshareReply extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.AuthByzCoin) - AuthByzCoinOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.ReshareReply) + ReshareReplyOrBuilder { private static final long serialVersionUID = 0L; - // Use AuthByzCoin.newBuilder() to construct. - private AuthByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use ReshareReply.newBuilder() to construct. + private ReshareReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private AuthByzCoin() { - byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + private ReshareReply() { + sig_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -3656,7 +3751,7 @@ private AuthByzCoin() { getUnknownFields() { return this.unknownFields; } - private AuthByzCoin( + private ReshareReply( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -3677,12 +3772,7 @@ private AuthByzCoin( break; case 10: { bitField0_ |= 0x00000001; - byzcoinid_ = input.readBytes(); - break; - } - case 16: { - bitField0_ |= 0x00000002; - ttl_ = input.readUInt64(); + sig_ = input.readBytes(); break; } default: { @@ -3706,46 +3796,31 @@ private AuthByzCoin( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthByzCoin_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder.class); + ch.epfl.dedis.lib.proto.OCS.ReshareReply.class, ch.epfl.dedis.lib.proto.OCS.ReshareReply.Builder.class); } private int bitField0_; - public static final int BYZCOINID_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString byzcoinid_; + public static final int SIG_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString sig_; /** - * required bytes byzcoinid = 1; + * required bytes sig = 1; */ - public boolean hasByzcoinid() { + public boolean hasSig() { return ((bitField0_ & 0x00000001) != 0); } /** - * required bytes byzcoinid = 1; - */ - public com.google.protobuf.ByteString getByzcoinid() { - return byzcoinid_; - } - - public static final int TTL_FIELD_NUMBER = 2; - private long ttl_; - /** - * required uint64 ttl = 2; - */ - public boolean hasTtl() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * required uint64 ttl = 2; + * required bytes sig = 1; */ - public long getTtl() { - return ttl_; + public com.google.protobuf.ByteString getSig() { + return sig_; } private byte memoizedIsInitialized = -1; @@ -3755,11 +3830,7 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasByzcoinid()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasTtl()) { + if (!hasSig()) { memoizedIsInitialized = 0; return false; } @@ -3771,10 +3842,7 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, byzcoinid_); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeUInt64(2, ttl_); + output.writeBytes(1, sig_); } unknownFields.writeTo(output); } @@ -3787,11 +3855,7 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, byzcoinid_); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt64Size(2, ttl_); + .computeBytesSize(1, sig_); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -3803,20 +3867,15 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthByzCoin)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.ReshareReply)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin other = (ch.epfl.dedis.lib.proto.OCS.AuthByzCoin) obj; + ch.epfl.dedis.lib.proto.OCS.ReshareReply other = (ch.epfl.dedis.lib.proto.OCS.ReshareReply) obj; - if (hasByzcoinid() != other.hasByzcoinid()) return false; - if (hasByzcoinid()) { - if (!getByzcoinid() - .equals(other.getByzcoinid())) return false; - } - if (hasTtl() != other.hasTtl()) return false; - if (hasTtl()) { - if (getTtl() - != other.getTtl()) return false; + if (hasSig() != other.hasSig()) return false; + if (hasSig()) { + if (!getSig() + .equals(other.getSig())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -3829,83 +3888,78 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasByzcoinid()) { - hash = (37 * hash) + BYZCOINID_FIELD_NUMBER; - hash = (53 * hash) + getByzcoinid().hashCode(); - } - if (hasTtl()) { - hash = (37 * hash) + TTL_FIELD_NUMBER; - hash = (53 * hash) + com.google.protobuf.Internal.hashLong( - getTtl()); + if (hasSig()) { + hash = (37 * hash) + SIG_FIELD_NUMBER; + hash = (53 * hash) + getSig().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3918,7 +3972,7 @@ public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthByzCoin prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.ReshareReply prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -3935,32 +3989,31 @@ protected Builder newBuilderForType( } /** *
-     * AuthByzCoin holds the information necessary to authenticate a byzcoin request.
-     * In the ByzCoin model, all requests are valid as long as they are stored in the
-     * blockchain with the given ID.
-     * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+     * ReshareReply is returned if the resharing has been completed successfully
+     * and contains the collective signature on the message
+     *   sha256( X | NewRoster )
      * 
* - * Protobuf type {@code ocs.AuthByzCoin} + * Protobuf type {@code ocs.ReshareReply} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.AuthByzCoin) - ch.epfl.dedis.lib.proto.OCS.AuthByzCoinOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.ReshareReply) + ch.epfl.dedis.lib.proto.OCS.ReshareReplyOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthByzCoin_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.Builder.class); + ch.epfl.dedis.lib.proto.OCS.ReshareReply.class, ch.epfl.dedis.lib.proto.OCS.ReshareReply.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.ReshareReply.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -3978,27 +4031,25 @@ private void maybeForceBuilderInitialization() { @java.lang.Override public Builder clear() { super.clear(); - byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + sig_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); - ttl_ = 0L; - bitField0_ = (bitField0_ & ~0x00000002); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.ReshareReply getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.ReshareReply.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin build() { - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.ReshareReply build() { + ch.epfl.dedis.lib.proto.OCS.ReshareReply result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -4006,18 +4057,14 @@ public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin buildPartial() { - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin result = new ch.epfl.dedis.lib.proto.OCS.AuthByzCoin(this); + public ch.epfl.dedis.lib.proto.OCS.ReshareReply buildPartial() { + ch.epfl.dedis.lib.proto.OCS.ReshareReply result = new ch.epfl.dedis.lib.proto.OCS.ReshareReply(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { to_bitField0_ |= 0x00000001; } - result.byzcoinid_ = byzcoinid_; - if (((from_bitField0_ & 0x00000002) != 0)) { - result.ttl_ = ttl_; - to_bitField0_ |= 0x00000002; - } + result.sig_ = sig_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -4057,21 +4104,18 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthByzCoin) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthByzCoin)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.ReshareReply) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.ReshareReply)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthByzCoin other) { - if (other == ch.epfl.dedis.lib.proto.OCS.AuthByzCoin.getDefaultInstance()) return this; - if (other.hasByzcoinid()) { - setByzcoinid(other.getByzcoinid()); - } - if (other.hasTtl()) { - setTtl(other.getTtl()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.ReshareReply other) { + if (other == ch.epfl.dedis.lib.proto.OCS.ReshareReply.getDefaultInstance()) return this; + if (other.hasSig()) { + setSig(other.getSig()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -4080,10 +4124,7 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthByzCoin other) { @java.lang.Override public final boolean isInitialized() { - if (!hasByzcoinid()) { - return false; - } - if (!hasTtl()) { + if (!hasSig()) { return false; } return true; @@ -4094,11 +4135,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.AuthByzCoin parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.ReshareReply parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthByzCoin) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.ReshareReply) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -4109,69 +4150,37 @@ public Builder mergeFrom( } private int bitField0_; - private com.google.protobuf.ByteString byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + private com.google.protobuf.ByteString sig_ = com.google.protobuf.ByteString.EMPTY; /** - * required bytes byzcoinid = 1; + * required bytes sig = 1; */ - public boolean hasByzcoinid() { + public boolean hasSig() { return ((bitField0_ & 0x00000001) != 0); } /** - * required bytes byzcoinid = 1; + * required bytes sig = 1; */ - public com.google.protobuf.ByteString getByzcoinid() { - return byzcoinid_; + public com.google.protobuf.ByteString getSig() { + return sig_; } /** - * required bytes byzcoinid = 1; + * required bytes sig = 1; */ - public Builder setByzcoinid(com.google.protobuf.ByteString value) { + public Builder setSig(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000001; - byzcoinid_ = value; + sig_ = value; onChanged(); return this; } /** - * required bytes byzcoinid = 1; + * required bytes sig = 1; */ - public Builder clearByzcoinid() { + public Builder clearSig() { bitField0_ = (bitField0_ & ~0x00000001); - byzcoinid_ = getDefaultInstance().getByzcoinid(); - onChanged(); - return this; - } - - private long ttl_ ; - /** - * required uint64 ttl = 2; - */ - public boolean hasTtl() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * required uint64 ttl = 2; - */ - public long getTtl() { - return ttl_; - } - /** - * required uint64 ttl = 2; - */ - public Builder setTtl(long value) { - bitField0_ |= 0x00000002; - ttl_ = value; - onChanged(); - return this; - } - /** - * required uint64 ttl = 2; - */ - public Builder clearTtl() { - bitField0_ = (bitField0_ & ~0x00000002); - ttl_ = 0L; + sig_ = getDefaultInstance().getSig(); onChanged(); return this; } @@ -4188,106 +4197,98 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.AuthByzCoin) + // @@protoc_insertion_point(builder_scope:ocs.ReshareReply) } - // @@protoc_insertion_point(class_scope:ocs.AuthByzCoin) - private static final ch.epfl.dedis.lib.proto.OCS.AuthByzCoin DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.ReshareReply) + private static final ch.epfl.dedis.lib.proto.OCS.ReshareReply DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthByzCoin(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.ReshareReply(); } - public static ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public AuthByzCoin parsePartialFrom( + public ReshareReply parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new AuthByzCoin(input, extensionRegistry); + return new ReshareReply(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthByzCoin getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.ReshareReply getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface AuthX509CertOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.AuthX509Cert) + public interface PolicyOCSOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.PolicyOCS) com.google.protobuf.MessageOrBuilder { /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; + * required .ocs.Policy policyreencrypt = 1; */ - java.util.List getCaList(); + boolean hasPolicyreencrypt(); /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; + * required .ocs.Policy policyreencrypt = 1; */ - int getCaCount(); + ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt(); /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; + * required .ocs.Policy policyreencrypt = 1; */ - com.google.protobuf.ByteString getCa(int index); + ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder(); /** - * required sint32 threshold = 2; + * required .ocs.Policy policyreshare = 2; */ - boolean hasThreshold(); + boolean hasPolicyreshare(); /** - * required sint32 threshold = 2; + * required .ocs.Policy policyreshare = 2; */ - int getThreshold(); + ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare(); + /** + * required .ocs.Policy policyreshare = 2; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder(); } /** *
-   * AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
-   * request. In its simplest form, it is simply the CA that will have to sign the
-   * certificates of the requesters.
-   * The Threshold indicates how many clients must have signed the request before it
-   * is accepted.
+   * PolicyOCS holds the two policies necessary to define an OCS: how to
+   * authenticate a reencryption request, and how to authenticate a
+   * resharing request.
+   * In the current form, both policies point to the same structure. If at
+   * a later moment a new access control backend is added, it might be that
+   * the policies will differ for this new backend.
    * 
* - * Protobuf type {@code ocs.AuthX509Cert} + * Protobuf type {@code ocs.PolicyOCS} */ - public static final class AuthX509Cert extends + public static final class PolicyOCS extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.AuthX509Cert) - AuthX509CertOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.PolicyOCS) + PolicyOCSOrBuilder { private static final long serialVersionUID = 0L; - // Use AuthX509Cert.newBuilder() to construct. - private AuthX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use PolicyOCS.newBuilder() to construct. + private PolicyOCS(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private AuthX509Cert() { - ca_ = java.util.Collections.emptyList(); + private PolicyOCS() { } @java.lang.Override @@ -4295,7 +4296,7 @@ private AuthX509Cert() { getUnknownFields() { return this.unknownFields; } - private AuthX509Cert( + private PolicyOCS( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -4315,16 +4316,29 @@ private AuthX509Cert( done = true; break; case 10: { - if (!((mutable_bitField0_ & 0x00000001) != 0)) { - ca_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000001; + ch.epfl.dedis.lib.proto.OCS.Policy.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = policyreencrypt_.toBuilder(); } - ca_.add(input.readBytes()); + policyreencrypt_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Policy.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(policyreencrypt_); + policyreencrypt_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; break; } - case 16: { - bitField0_ |= 0x00000001; - threshold_ = input.readSInt32(); + case 18: { + ch.epfl.dedis.lib.proto.OCS.Policy.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = policyreshare_.toBuilder(); + } + policyreshare_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Policy.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(policyreshare_); + policyreshare_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; break; } default: { @@ -4342,74 +4356,4648 @@ private AuthX509Cert( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { - if (((mutable_bitField0_ & 0x00000001) != 0)) { - ca_ = java.util.Collections.unmodifiableList(ca_); // C - } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyOCS_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthX509Cert_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyOCS_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder.class); + ch.epfl.dedis.lib.proto.OCS.PolicyOCS.class, ch.epfl.dedis.lib.proto.OCS.PolicyOCS.Builder.class); } private int bitField0_; - public static final int CA_FIELD_NUMBER = 1; - private java.util.List ca_; + public static final int POLICYREENCRYPT_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OCS.Policy policyreencrypt_; /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; + * required .ocs.Policy policyreencrypt = 1; */ - public java.util.List - getCaList() { - return ca_; + public boolean hasPolicyreencrypt() { + return ((bitField0_ & 0x00000001) != 0); } /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; + * required .ocs.Policy policyreencrypt = 1; */ - public int getCaCount() { - return ca_.size(); + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt() { + return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; } /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
+ * required .ocs.Policy policyreencrypt = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder() { + return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + } + + public static final int POLICYRESHARE_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.Policy policyreshare_; + /** + * required .ocs.Policy policyreshare = 2; + */ + public boolean hasPolicyreshare() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .ocs.Policy policyreshare = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare() { + return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + } + /** + * required .ocs.Policy policyreshare = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder() { + return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasPolicyreencrypt()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPolicyreshare()) { + memoizedIsInitialized = 0; + return false; + } + if (!getPolicyreencrypt().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getPolicyreshare().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getPolicyreencrypt()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getPolicyreshare()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getPolicyreencrypt()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getPolicyreshare()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.PolicyOCS)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.PolicyOCS other = (ch.epfl.dedis.lib.proto.OCS.PolicyOCS) obj; + + if (hasPolicyreencrypt() != other.hasPolicyreencrypt()) return false; + if (hasPolicyreencrypt()) { + if (!getPolicyreencrypt() + .equals(other.getPolicyreencrypt())) return false; + } + if (hasPolicyreshare() != other.hasPolicyreshare()) return false; + if (hasPolicyreshare()) { + if (!getPolicyreshare() + .equals(other.getPolicyreshare())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasPolicyreencrypt()) { + hash = (37 * hash) + POLICYREENCRYPT_FIELD_NUMBER; + hash = (53 * hash) + getPolicyreencrypt().hashCode(); + } + if (hasPolicyreshare()) { + hash = (37 * hash) + POLICYRESHARE_FIELD_NUMBER; + hash = (53 * hash) + getPolicyreshare().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.PolicyOCS prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * PolicyOCS holds the two policies necessary to define an OCS: how to
+     * authenticate a reencryption request, and how to authenticate a
+     * resharing request.
+     * In the current form, both policies point to the same structure. If at
+     * a later moment a new access control backend is added, it might be that
+     * the policies will differ for this new backend.
+     * 
* - * repeated bytes ca = 1; + * Protobuf type {@code ocs.PolicyOCS} */ - public com.google.protobuf.ByteString getCa(int index) { - return ca_.get(index); + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.PolicyOCS) + ch.epfl.dedis.lib.proto.OCS.PolicyOCSOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyOCS_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyOCS_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.PolicyOCS.class, ch.epfl.dedis.lib.proto.OCS.PolicyOCS.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.PolicyOCS.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getPolicyreencryptFieldBuilder(); + getPolicyreshareFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (policyreencryptBuilder_ == null) { + policyreencrypt_ = null; + } else { + policyreencryptBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (policyreshareBuilder_ == null) { + policyreshare_ = null; + } else { + policyreshareBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyOCS_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyOCS getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.PolicyOCS.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyOCS build() { + ch.epfl.dedis.lib.proto.OCS.PolicyOCS result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyOCS buildPartial() { + ch.epfl.dedis.lib.proto.OCS.PolicyOCS result = new ch.epfl.dedis.lib.proto.OCS.PolicyOCS(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + if (policyreencryptBuilder_ == null) { + result.policyreencrypt_ = policyreencrypt_; + } else { + result.policyreencrypt_ = policyreencryptBuilder_.build(); + } + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + if (policyreshareBuilder_ == null) { + result.policyreshare_ = policyreshare_; + } else { + result.policyreshare_ = policyreshareBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.PolicyOCS) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.PolicyOCS)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.PolicyOCS other) { + if (other == ch.epfl.dedis.lib.proto.OCS.PolicyOCS.getDefaultInstance()) return this; + if (other.hasPolicyreencrypt()) { + mergePolicyreencrypt(other.getPolicyreencrypt()); + } + if (other.hasPolicyreshare()) { + mergePolicyreshare(other.getPolicyreshare()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasPolicyreencrypt()) { + return false; + } + if (!hasPolicyreshare()) { + return false; + } + if (!getPolicyreencrypt().isInitialized()) { + return false; + } + if (!getPolicyreshare().isInitialized()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.PolicyOCS parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.PolicyOCS) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private ch.epfl.dedis.lib.proto.OCS.Policy policyreencrypt_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> policyreencryptBuilder_; + /** + * required .ocs.Policy policyreencrypt = 1; + */ + public boolean hasPolicyreencrypt() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required .ocs.Policy policyreencrypt = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt() { + if (policyreencryptBuilder_ == null) { + return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + } else { + return policyreencryptBuilder_.getMessage(); + } + } + /** + * required .ocs.Policy policyreencrypt = 1; + */ + public Builder setPolicyreencrypt(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreencryptBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + policyreencrypt_ = value; + onChanged(); + } else { + policyreencryptBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .ocs.Policy policyreencrypt = 1; + */ + public Builder setPolicyreencrypt( + ch.epfl.dedis.lib.proto.OCS.Policy.Builder builderForValue) { + if (policyreencryptBuilder_ == null) { + policyreencrypt_ = builderForValue.build(); + onChanged(); + } else { + policyreencryptBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .ocs.Policy policyreencrypt = 1; + */ + public Builder mergePolicyreencrypt(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreencryptBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + policyreencrypt_ != null && + policyreencrypt_ != ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) { + policyreencrypt_ = + ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder(policyreencrypt_).mergeFrom(value).buildPartial(); + } else { + policyreencrypt_ = value; + } + onChanged(); + } else { + policyreencryptBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .ocs.Policy policyreencrypt = 1; + */ + public Builder clearPolicyreencrypt() { + if (policyreencryptBuilder_ == null) { + policyreencrypt_ = null; + onChanged(); + } else { + policyreencryptBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .ocs.Policy policyreencrypt = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy.Builder getPolicyreencryptBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getPolicyreencryptFieldBuilder().getBuilder(); + } + /** + * required .ocs.Policy policyreencrypt = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder() { + if (policyreencryptBuilder_ != null) { + return policyreencryptBuilder_.getMessageOrBuilder(); + } else { + return policyreencrypt_ == null ? + ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + } + } + /** + * required .ocs.Policy policyreencrypt = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> + getPolicyreencryptFieldBuilder() { + if (policyreencryptBuilder_ == null) { + policyreencryptBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder>( + getPolicyreencrypt(), + getParentForChildren(), + isClean()); + policyreencrypt_ = null; + } + return policyreencryptBuilder_; + } + + private ch.epfl.dedis.lib.proto.OCS.Policy policyreshare_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> policyreshareBuilder_; + /** + * required .ocs.Policy policyreshare = 2; + */ + public boolean hasPolicyreshare() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .ocs.Policy policyreshare = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare() { + if (policyreshareBuilder_ == null) { + return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + } else { + return policyreshareBuilder_.getMessage(); + } + } + /** + * required .ocs.Policy policyreshare = 2; + */ + public Builder setPolicyreshare(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreshareBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + policyreshare_ = value; + onChanged(); + } else { + policyreshareBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.Policy policyreshare = 2; + */ + public Builder setPolicyreshare( + ch.epfl.dedis.lib.proto.OCS.Policy.Builder builderForValue) { + if (policyreshareBuilder_ == null) { + policyreshare_ = builderForValue.build(); + onChanged(); + } else { + policyreshareBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.Policy policyreshare = 2; + */ + public Builder mergePolicyreshare(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreshareBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + policyreshare_ != null && + policyreshare_ != ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) { + policyreshare_ = + ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder(policyreshare_).mergeFrom(value).buildPartial(); + } else { + policyreshare_ = value; + } + onChanged(); + } else { + policyreshareBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.Policy policyreshare = 2; + */ + public Builder clearPolicyreshare() { + if (policyreshareBuilder_ == null) { + policyreshare_ = null; + onChanged(); + } else { + policyreshareBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * required .ocs.Policy policyreshare = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy.Builder getPolicyreshareBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getPolicyreshareFieldBuilder().getBuilder(); + } + /** + * required .ocs.Policy policyreshare = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder() { + if (policyreshareBuilder_ != null) { + return policyreshareBuilder_.getMessageOrBuilder(); + } else { + return policyreshare_ == null ? + ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + } + } + /** + * required .ocs.Policy policyreshare = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> + getPolicyreshareFieldBuilder() { + if (policyreshareBuilder_ == null) { + policyreshareBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder>( + getPolicyreshare(), + getParentForChildren(), + isClean()); + policyreshare_ = null; + } + return policyreshareBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.PolicyOCS) + } + + // @@protoc_insertion_point(class_scope:ocs.PolicyOCS) + private static final ch.epfl.dedis.lib.proto.OCS.PolicyOCS DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.PolicyOCS(); + } + + public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public PolicyOCS parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new PolicyOCS(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyOCS getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface PolicyOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.Policy) + com.google.protobuf.MessageOrBuilder { + + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + boolean hasByzcoin(); + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getByzcoin(); + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder getByzcoinOrBuilder(); + + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + boolean hasAuthx509Cert(); + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getAuthx509Cert(); + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder getAuthx509CertOrBuilder(); + } + /** + *
+   * Policy holds all possible authentication structures. When using it to call
+   * Authorise, only one of the fields must be non-nil.
+   * 
+ * + * Protobuf type {@code ocs.Policy} + */ + public static final class Policy extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.Policy) + PolicyOrBuilder { + private static final long serialVersionUID = 0L; + // Use Policy.newBuilder() to construct. + private Policy(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Policy() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Policy( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = byzcoin_.toBuilder(); + } + byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(byzcoin_); + byzcoin_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = authx509Cert_.toBuilder(); + } + authx509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(authx509Cert_); + authx509Cert_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Policy.class, ch.epfl.dedis.lib.proto.OCS.Policy.Builder.class); + } + + private int bitField0_; + public static final int BYZCOIN_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin byzcoin_; + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getByzcoin() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder getByzcoinOrBuilder() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; + } + + public static final int AUTHX509CERT_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert authx509Cert_; + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + public boolean hasAuthx509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getAuthx509Cert() { + return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : authx509Cert_; + } + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder getAuthx509CertOrBuilder() { + return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : authx509Cert_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasAuthx509Cert()) { + if (!getAuthx509Cert().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getAuthx509Cert()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getAuthx509Cert()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Policy)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.Policy other = (ch.epfl.dedis.lib.proto.OCS.Policy) obj; + + if (hasByzcoin() != other.hasByzcoin()) return false; + if (hasByzcoin()) { + if (!getByzcoin() + .equals(other.getByzcoin())) return false; + } + if (hasAuthx509Cert() != other.hasAuthx509Cert()) return false; + if (hasAuthx509Cert()) { + if (!getAuthx509Cert() + .equals(other.getAuthx509Cert())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasByzcoin()) { + hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; + hash = (53 * hash) + getByzcoin().hashCode(); + } + if (hasAuthx509Cert()) { + hash = (37 * hash) + AUTHX509CERT_FIELD_NUMBER; + hash = (53 * hash) + getAuthx509Cert().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Policy prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Policy holds all possible authentication structures. When using it to call
+     * Authorise, only one of the fields must be non-nil.
+     * 
+ * + * Protobuf type {@code ocs.Policy} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.Policy) + ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Policy.class, ch.epfl.dedis.lib.proto.OCS.Policy.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getByzcoinFieldBuilder(); + getAuthx509CertFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (authx509CertBuilder_ == null) { + authx509Cert_ = null; + } else { + authx509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Policy getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Policy build() { + ch.epfl.dedis.lib.proto.OCS.Policy result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Policy buildPartial() { + ch.epfl.dedis.lib.proto.OCS.Policy result = new ch.epfl.dedis.lib.proto.OCS.Policy(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + if (byzcoinBuilder_ == null) { + result.byzcoin_ = byzcoin_; + } else { + result.byzcoin_ = byzcoinBuilder_.build(); + } + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + if (authx509CertBuilder_ == null) { + result.authx509Cert_ = authx509Cert_; + } else { + result.authx509Cert_ = authx509CertBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.Policy) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Policy)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Policy other) { + if (other == ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) return this; + if (other.hasByzcoin()) { + mergeByzcoin(other.getByzcoin()); + } + if (other.hasAuthx509Cert()) { + mergeAuthx509Cert(other.getAuthx509Cert()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + return false; + } + } + if (hasAuthx509Cert()) { + if (!getAuthx509Cert().isInitialized()) { + return false; + } + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.Policy parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Policy) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin byzcoin_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder> byzcoinBuilder_; + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getByzcoin() { + if (byzcoinBuilder_ == null) { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; + } else { + return byzcoinBuilder_.getMessage(); + } + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin value) { + if (byzcoinBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + byzcoin_ = value; + onChanged(); + } else { + byzcoinBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public Builder setByzcoin( + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder builderForValue) { + if (byzcoinBuilder_ == null) { + byzcoin_ = builderForValue.build(); + onChanged(); + } else { + byzcoinBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin value) { + if (byzcoinBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + byzcoin_ != null && + byzcoin_ != ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance()) { + byzcoin_ = + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); + } else { + byzcoin_ = value; + } + onChanged(); + } else { + byzcoinBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public Builder clearByzcoin() { + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + onChanged(); + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder getByzcoinBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getByzcoinFieldBuilder().getBuilder(); + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder getByzcoinOrBuilder() { + if (byzcoinBuilder_ != null) { + return byzcoinBuilder_.getMessageOrBuilder(); + } else { + return byzcoin_ == null ? + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; + } + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder> + getByzcoinFieldBuilder() { + if (byzcoinBuilder_ == null) { + byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder>( + getByzcoin(), + getParentForChildren(), + isClean()); + byzcoin_ = null; + } + return byzcoinBuilder_; + } + + private ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert authx509Cert_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder> authx509CertBuilder_; + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + public boolean hasAuthx509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getAuthx509Cert() { + if (authx509CertBuilder_ == null) { + return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : authx509Cert_; + } else { + return authx509CertBuilder_.getMessage(); + } + } + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + public Builder setAuthx509Cert(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert value) { + if (authx509CertBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + authx509Cert_ = value; + onChanged(); + } else { + authx509CertBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + public Builder setAuthx509Cert( + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder builderForValue) { + if (authx509CertBuilder_ == null) { + authx509Cert_ = builderForValue.build(); + onChanged(); + } else { + authx509CertBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + public Builder mergeAuthx509Cert(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert value) { + if (authx509CertBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + authx509Cert_ != null && + authx509Cert_ != ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance()) { + authx509Cert_ = + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.newBuilder(authx509Cert_).mergeFrom(value).buildPartial(); + } else { + authx509Cert_ = value; + } + onChanged(); + } else { + authx509CertBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + public Builder clearAuthx509Cert() { + if (authx509CertBuilder_ == null) { + authx509Cert_ = null; + onChanged(); + } else { + authx509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder getAuthx509CertBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getAuthx509CertFieldBuilder().getBuilder(); + } + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder getAuthx509CertOrBuilder() { + if (authx509CertBuilder_ != null) { + return authx509CertBuilder_.getMessageOrBuilder(); + } else { + return authx509Cert_ == null ? + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : authx509Cert_; + } + } + /** + * optional .ocs.PolicyX509Cert authx509cert = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder> + getAuthx509CertFieldBuilder() { + if (authx509CertBuilder_ == null) { + authx509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder>( + getAuthx509Cert(), + getParentForChildren(), + isClean()); + authx509Cert_ = null; + } + return authx509CertBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.Policy) + } + + // @@protoc_insertion_point(class_scope:ocs.Policy) + private static final ch.epfl.dedis.lib.proto.OCS.Policy DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Policy(); + } + + public static ch.epfl.dedis.lib.proto.OCS.Policy getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Policy parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Policy(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Policy getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface PolicyByzCoinOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.PolicyByzCoin) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes byzcoinid = 1; + */ + boolean hasByzcoinid(); + /** + * required bytes byzcoinid = 1; + */ + com.google.protobuf.ByteString getByzcoinid(); + + /** + * required uint64 ttl = 2; + */ + boolean hasTtl(); + /** + * required uint64 ttl = 2; + */ + long getTtl(); + } + /** + *
+   * PolicyByzCoin holds the information necessary to authenticate a byzcoin request.
+   * In the ByzCoin model, all requests are valid as long as they are stored in the
+   * blockchain with the given ID.
+   * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+   * 
+ * + * Protobuf type {@code ocs.PolicyByzCoin} + */ + public static final class PolicyByzCoin extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.PolicyByzCoin) + PolicyByzCoinOrBuilder { + private static final long serialVersionUID = 0L; + // Use PolicyByzCoin.newBuilder() to construct. + private PolicyByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private PolicyByzCoin() { + byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private PolicyByzCoin( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + byzcoinid_ = input.readBytes(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + ttl_ = input.readUInt64(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.class, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder.class); + } + + private int bitField0_; + public static final int BYZCOINID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString byzcoinid_; + /** + * required bytes byzcoinid = 1; + */ + public boolean hasByzcoinid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes byzcoinid = 1; + */ + public com.google.protobuf.ByteString getByzcoinid() { + return byzcoinid_; + } + + public static final int TTL_FIELD_NUMBER = 2; + private long ttl_; + /** + * required uint64 ttl = 2; + */ + public boolean hasTtl() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required uint64 ttl = 2; + */ + public long getTtl() { + return ttl_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasByzcoinid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTtl()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, byzcoinid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeUInt64(2, ttl_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, byzcoinid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(2, ttl_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin other = (ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin) obj; + + if (hasByzcoinid() != other.hasByzcoinid()) return false; + if (hasByzcoinid()) { + if (!getByzcoinid() + .equals(other.getByzcoinid())) return false; + } + if (hasTtl() != other.hasTtl()) return false; + if (hasTtl()) { + if (getTtl() + != other.getTtl()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasByzcoinid()) { + hash = (37 * hash) + BYZCOINID_FIELD_NUMBER; + hash = (53 * hash) + getByzcoinid().hashCode(); + } + if (hasTtl()) { + hash = (37 * hash) + TTL_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getTtl()); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * PolicyByzCoin holds the information necessary to authenticate a byzcoin request.
+     * In the ByzCoin model, all requests are valid as long as they are stored in the
+     * blockchain with the given ID.
+     * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+     * 
+ * + * Protobuf type {@code ocs.PolicyByzCoin} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.PolicyByzCoin) + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.class, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + ttl_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin build() { + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin buildPartial() { + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin result = new ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.byzcoinid_ = byzcoinid_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.ttl_ = ttl_; + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin other) { + if (other == ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance()) return this; + if (other.hasByzcoinid()) { + setByzcoinid(other.getByzcoinid()); + } + if (other.hasTtl()) { + setTtl(other.getTtl()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasByzcoinid()) { + return false; + } + if (!hasTtl()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes byzcoinid = 1; + */ + public boolean hasByzcoinid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes byzcoinid = 1; + */ + public com.google.protobuf.ByteString getByzcoinid() { + return byzcoinid_; + } + /** + * required bytes byzcoinid = 1; + */ + public Builder setByzcoinid(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + byzcoinid_ = value; + onChanged(); + return this; + } + /** + * required bytes byzcoinid = 1; + */ + public Builder clearByzcoinid() { + bitField0_ = (bitField0_ & ~0x00000001); + byzcoinid_ = getDefaultInstance().getByzcoinid(); + onChanged(); + return this; + } + + private long ttl_ ; + /** + * required uint64 ttl = 2; + */ + public boolean hasTtl() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required uint64 ttl = 2; + */ + public long getTtl() { + return ttl_; + } + /** + * required uint64 ttl = 2; + */ + public Builder setTtl(long value) { + bitField0_ |= 0x00000002; + ttl_ = value; + onChanged(); + return this; + } + /** + * required uint64 ttl = 2; + */ + public Builder clearTtl() { + bitField0_ = (bitField0_ & ~0x00000002); + ttl_ = 0L; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.PolicyByzCoin) + } + + // @@protoc_insertion_point(class_scope:ocs.PolicyByzCoin) + private static final ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin(); + } + + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public PolicyByzCoin parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new PolicyByzCoin(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface PolicyX509CertOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.PolicyX509Cert) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + java.util.List getCaList(); + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + int getCaCount(); + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + com.google.protobuf.ByteString getCa(int index); + + /** + * required sint32 threshold = 2; + */ + boolean hasThreshold(); + /** + * required sint32 threshold = 2; + */ + int getThreshold(); + } + /** + *
+   * PolicyX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
+   * request. In its simplest form, it is simply the CA that will have to sign the
+   * certificates of the requesters.
+   * The Threshold indicates how many clients must have signed the request before it
+   * is accepted.
+   * 
+ * + * Protobuf type {@code ocs.PolicyX509Cert} + */ + public static final class PolicyX509Cert extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.PolicyX509Cert) + PolicyX509CertOrBuilder { + private static final long serialVersionUID = 0L; + // Use PolicyX509Cert.newBuilder() to construct. + private PolicyX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private PolicyX509Cert() { + ca_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private PolicyX509Cert( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + ca_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + ca_.add(input.readBytes()); + break; + } + case 16: { + bitField0_ |= 0x00000001; + threshold_ = input.readSInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + ca_ = java.util.Collections.unmodifiableList(ca_); // C + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.class, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder.class); + } + + private int bitField0_; + public static final int CA_FIELD_NUMBER = 1; + private java.util.List ca_; + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public java.util.List + getCaList() { + return ca_; + } + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public int getCaCount() { + return ca_.size(); + } + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public com.google.protobuf.ByteString getCa(int index) { + return ca_.get(index); + } + + public static final int THRESHOLD_FIELD_NUMBER = 2; + private int threshold_; + /** + * required sint32 threshold = 2; + */ + public boolean hasThreshold() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required sint32 threshold = 2; + */ + public int getThreshold() { + return threshold_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasThreshold()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < ca_.size(); i++) { + output.writeBytes(1, ca_.get(i)); + } + if (((bitField0_ & 0x00000001) != 0)) { + output.writeSInt32(2, threshold_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < ca_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(ca_.get(i)); + } + size += dataSize; + size += 1 * getCaList().size(); + } + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeSInt32Size(2, threshold_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert other = (ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert) obj; + + if (!getCaList() + .equals(other.getCaList())) return false; + if (hasThreshold() != other.hasThreshold()) return false; + if (hasThreshold()) { + if (getThreshold() + != other.getThreshold()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getCaCount() > 0) { + hash = (37 * hash) + CA_FIELD_NUMBER; + hash = (53 * hash) + getCaList().hashCode(); + } + if (hasThreshold()) { + hash = (37 * hash) + THRESHOLD_FIELD_NUMBER; + hash = (53 * hash) + getThreshold(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * PolicyX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
+     * request. In its simplest form, it is simply the CA that will have to sign the
+     * certificates of the requesters.
+     * The Threshold indicates how many clients must have signed the request before it
+     * is accepted.
+     * 
+ * + * Protobuf type {@code ocs.PolicyX509Cert} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.PolicyX509Cert) + ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.class, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + ca_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + threshold_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert build() { + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert buildPartial() { + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert result = new ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((bitField0_ & 0x00000001) != 0)) { + ca_ = java.util.Collections.unmodifiableList(ca_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.ca_ = ca_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.threshold_ = threshold_; + to_bitField0_ |= 0x00000001; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert other) { + if (other == ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance()) return this; + if (!other.ca_.isEmpty()) { + if (ca_.isEmpty()) { + ca_ = other.ca_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureCaIsMutable(); + ca_.addAll(other.ca_); + } + onChanged(); + } + if (other.hasThreshold()) { + setThreshold(other.getThreshold()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasThreshold()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.util.List ca_ = java.util.Collections.emptyList(); + private void ensureCaIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + ca_ = new java.util.ArrayList(ca_); + bitField0_ |= 0x00000001; + } + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public java.util.List + getCaList() { + return ((bitField0_ & 0x00000001) != 0) ? + java.util.Collections.unmodifiableList(ca_) : ca_; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public int getCaCount() { + return ca_.size(); + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public com.google.protobuf.ByteString getCa(int index) { + return ca_.get(index); + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder setCa( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCaIsMutable(); + ca_.set(index, value); + onChanged(); + return this; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder addCa(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCaIsMutable(); + ca_.add(value); + onChanged(); + return this; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder addAllCa( + java.lang.Iterable values) { + ensureCaIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, ca_); + onChanged(); + return this; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder clearCa() { + ca_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + + private int threshold_ ; + /** + * required sint32 threshold = 2; + */ + public boolean hasThreshold() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required sint32 threshold = 2; + */ + public int getThreshold() { + return threshold_; + } + /** + * required sint32 threshold = 2; + */ + public Builder setThreshold(int value) { + bitField0_ |= 0x00000002; + threshold_ = value; + onChanged(); + return this; + } + /** + * required sint32 threshold = 2; + */ + public Builder clearThreshold() { + bitField0_ = (bitField0_ & ~0x00000002); + threshold_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.PolicyX509Cert) + } + + // @@protoc_insertion_point(class_scope:ocs.PolicyX509Cert) + private static final ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert(); + } + + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public PolicyX509Cert parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new PolicyX509Cert(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AuthReencryptOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReencrypt) + com.google.protobuf.MessageOrBuilder { + + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + boolean hasByzcoin(); + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getByzcoin(); + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder getByzcoinOrBuilder(); + + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + boolean hasX509Cert(); + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getX509Cert(); + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder getX509CertOrBuilder(); + } + /** + *
+   * AuthReencrypt holds one of the possible authentication proofs for a reencryption request. Each
+   * authentication proof must hold the secret to be reencrypted, the ephemeral key, as well
+   * as the proof itself that the request is valid. For each of the authentication
+   * schemes, this proof will be different.
+   * 
+ * + * Protobuf type {@code ocs.AuthReencrypt} + */ + public static final class AuthReencrypt extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.AuthReencrypt) + AuthReencryptOrBuilder { + private static final long serialVersionUID = 0L; + // Use AuthReencrypt.newBuilder() to construct. + private AuthReencrypt(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private AuthReencrypt() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AuthReencrypt( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = byzcoin_.toBuilder(); + } + byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(byzcoin_); + byzcoin_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = x509Cert_.toBuilder(); + } + x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(x509Cert_); + x509Cert_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.class, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder.class); + } + + private int bitField0_; + public static final int BYZCOIN_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin byzcoin_; + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getByzcoin() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder getByzcoinOrBuilder() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; + } + + public static final int X509CERT_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert x509Cert_; + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getX509Cert() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder getX509CertOrBuilder() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasX509Cert()) { + if (!getX509Cert().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getX509Cert()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getX509Cert()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencrypt)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt other = (ch.epfl.dedis.lib.proto.OCS.AuthReencrypt) obj; + + if (hasByzcoin() != other.hasByzcoin()) return false; + if (hasByzcoin()) { + if (!getByzcoin() + .equals(other.getByzcoin())) return false; + } + if (hasX509Cert() != other.hasX509Cert()) return false; + if (hasX509Cert()) { + if (!getX509Cert() + .equals(other.getX509Cert())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasByzcoin()) { + hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; + hash = (53 * hash) + getByzcoin().hashCode(); + } + if (hasX509Cert()) { + hash = (37 * hash) + X509CERT_FIELD_NUMBER; + hash = (53 * hash) + getX509Cert().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * AuthReencrypt holds one of the possible authentication proofs for a reencryption request. Each
+     * authentication proof must hold the secret to be reencrypted, the ephemeral key, as well
+     * as the proof itself that the request is valid. For each of the authentication
+     * schemes, this proof will be different.
+     * 
+ * + * Protobuf type {@code ocs.AuthReencrypt} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.AuthReencrypt) + ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.class, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getByzcoinFieldBuilder(); + getX509CertFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (x509CertBuilder_ == null) { + x509Cert_ = null; + } else { + x509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt build() { + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt result = new ch.epfl.dedis.lib.proto.OCS.AuthReencrypt(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + if (byzcoinBuilder_ == null) { + result.byzcoin_ = byzcoin_; + } else { + result.byzcoin_ = byzcoinBuilder_.build(); + } + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + if (x509CertBuilder_ == null) { + result.x509Cert_ = x509Cert_; + } else { + result.x509Cert_ = x509CertBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencrypt) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReencrypt)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance()) return this; + if (other.hasByzcoin()) { + mergeByzcoin(other.getByzcoin()); + } + if (other.hasX509Cert()) { + mergeX509Cert(other.getX509Cert()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + return false; + } + } + if (hasX509Cert()) { + if (!getX509Cert().isInitialized()) { + return false; + } + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReencrypt) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin byzcoin_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder> byzcoinBuilder_; + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getByzcoin() { + if (byzcoinBuilder_ == null) { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; + } else { + return byzcoinBuilder_.getMessage(); + } + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin value) { + if (byzcoinBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + byzcoin_ = value; + onChanged(); + } else { + byzcoinBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + public Builder setByzcoin( + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder builderForValue) { + if (byzcoinBuilder_ == null) { + byzcoin_ = builderForValue.build(); + onChanged(); + } else { + byzcoinBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin value) { + if (byzcoinBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + byzcoin_ != null && + byzcoin_ != ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance()) { + byzcoin_ = + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); + } else { + byzcoin_ = value; + } + onChanged(); + } else { + byzcoinBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + public Builder clearByzcoin() { + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + onChanged(); + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder getByzcoinBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getByzcoinFieldBuilder().getBuilder(); + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder getByzcoinOrBuilder() { + if (byzcoinBuilder_ != null) { + return byzcoinBuilder_.getMessageOrBuilder(); + } else { + return byzcoin_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; + } + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder> + getByzcoinFieldBuilder() { + if (byzcoinBuilder_ == null) { + byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder>( + getByzcoin(), + getParentForChildren(), + isClean()); + byzcoin_ = null; + } + return byzcoinBuilder_; + } + + private ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert x509Cert_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder> x509CertBuilder_; + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getX509Cert() { + if (x509CertBuilder_ == null) { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; + } else { + return x509CertBuilder_.getMessage(); + } + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + public Builder setX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert value) { + if (x509CertBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + x509Cert_ = value; + onChanged(); + } else { + x509CertBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + public Builder setX509Cert( + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder builderForValue) { + if (x509CertBuilder_ == null) { + x509Cert_ = builderForValue.build(); + onChanged(); + } else { + x509CertBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert value) { + if (x509CertBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + x509Cert_ != null && + x509Cert_ != ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance()) { + x509Cert_ = + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); + } else { + x509Cert_ = value; + } + onChanged(); + } else { + x509CertBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + public Builder clearX509Cert() { + if (x509CertBuilder_ == null) { + x509Cert_ = null; + onChanged(); + } else { + x509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder getX509CertBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getX509CertFieldBuilder().getBuilder(); + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder getX509CertOrBuilder() { + if (x509CertBuilder_ != null) { + return x509CertBuilder_.getMessageOrBuilder(); + } else { + return x509Cert_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; + } + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder> + getX509CertFieldBuilder() { + if (x509CertBuilder_ == null) { + x509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder>( + getX509Cert(), + getParentForChildren(), + isClean()); + x509Cert_ = null; + } + return x509CertBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.AuthReencrypt) + } + + // @@protoc_insertion_point(class_scope:ocs.AuthReencrypt) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReencrypt DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReencrypt(); + } + + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public AuthReencrypt parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AuthReencrypt(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AuthReencryptByzCoinOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReencryptByzCoin) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; + */ + boolean hasWrite(); + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; + */ + com.google.protobuf.ByteString getWrite(); + + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; + */ + boolean hasRead(); + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; + */ + com.google.protobuf.ByteString getRead(); + } + /** + *
+   * AuthReencryptByzCoin holds the proof of the write instance, holding the secret itself.
+   * The proof of the read instance holds the ephemeral key. Both proofs can be
+   * verified using one of the stored ByzCoinIDs.
+   * 
+ * + * Protobuf type {@code ocs.AuthReencryptByzCoin} + */ + public static final class AuthReencryptByzCoin extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.AuthReencryptByzCoin) + AuthReencryptByzCoinOrBuilder { + private static final long serialVersionUID = 0L; + // Use AuthReencryptByzCoin.newBuilder() to construct. + private AuthReencryptByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private AuthReencryptByzCoin() { + write_ = com.google.protobuf.ByteString.EMPTY; + read_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AuthReencryptByzCoin( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + write_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + read_ = input.readBytes(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder.class); + } + + private int bitField0_; + public static final int WRITE_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString write_; + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; + */ + public boolean hasWrite() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; + */ + public com.google.protobuf.ByteString getWrite() { + return write_; + } + + public static final int READ_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString read_; + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; + */ + public boolean hasRead() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; + */ + public com.google.protobuf.ByteString getRead() { + return read_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasWrite()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasRead()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, write_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeBytes(2, read_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, write_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, read_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin other = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin) obj; + + if (hasWrite() != other.hasWrite()) return false; + if (hasWrite()) { + if (!getWrite() + .equals(other.getWrite())) return false; + } + if (hasRead() != other.hasRead()) return false; + if (hasRead()) { + if (!getRead() + .equals(other.getRead())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasWrite()) { + hash = (37 * hash) + WRITE_FIELD_NUMBER; + hash = (53 * hash) + getWrite().hashCode(); + } + if (hasRead()) { + hash = (37 * hash) + READ_FIELD_NUMBER; + hash = (53 * hash) + getRead().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * AuthReencryptByzCoin holds the proof of the write instance, holding the secret itself.
+     * The proof of the read instance holds the ephemeral key. Both proofs can be
+     * verified using one of the stored ByzCoinIDs.
+     * 
+ * + * Protobuf type {@code ocs.AuthReencryptByzCoin} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.AuthReencryptByzCoin) + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + write_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + read_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin build() { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin result = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.write_ = write_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.read_ = read_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance()) return this; + if (other.hasWrite()) { + setWrite(other.getWrite()); + } + if (other.hasRead()) { + setRead(other.getRead()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasWrite()) { + return false; + } + if (!hasRead()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString write_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; + */ + public boolean hasWrite() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; + */ + public com.google.protobuf.ByteString getWrite() { + return write_; + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; + */ + public Builder setWrite(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + write_ = value; + onChanged(); + return this; + } + /** + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; + */ + public Builder clearWrite() { + bitField0_ = (bitField0_ & ~0x00000001); + write_ = getDefaultInstance().getWrite(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString read_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; + */ + public boolean hasRead() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; + */ + public com.google.protobuf.ByteString getRead() { + return read_; + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; + */ + public Builder setRead(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + read_ = value; + onChanged(); + return this; + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; + */ + public Builder clearRead() { + bitField0_ = (bitField0_ & ~0x00000002); + read_ = getDefaultInstance().getRead(); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.AuthReencryptByzCoin) + } + + // @@protoc_insertion_point(class_scope:ocs.AuthReencryptByzCoin) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin(); + } + + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public AuthReencryptByzCoin parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AuthReencryptByzCoin(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AuthReencryptX509CertOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReencryptX509Cert) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes secret = 1; + */ + boolean hasSecret(); + /** + * required bytes secret = 1; + */ + com.google.protobuf.ByteString getSecret(); + + /** + * repeated bytes certificates = 2; + */ + java.util.List getCertificatesList(); + /** + * repeated bytes certificates = 2; + */ + int getCertificatesCount(); + /** + * repeated bytes certificates = 2; + */ + com.google.protobuf.ByteString getCertificates(int index); + } + /** + *
+   * AuthReencryptX509Cert holds the proof that at least a threshold number of clients
+   * accepted the reencryption.
+   * For each client, there must exist a certificate that can be verified by the
+   * CA certificate from PolicyX509Cert. Additionally, each client must sign the
+   * following message:
+   *   sha256( Secret | Ephemeral | Time )
+   * 
+ * + * Protobuf type {@code ocs.AuthReencryptX509Cert} + */ + public static final class AuthReencryptX509Cert extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.AuthReencryptX509Cert) + AuthReencryptX509CertOrBuilder { + private static final long serialVersionUID = 0L; + // Use AuthReencryptX509Cert.newBuilder() to construct. + private AuthReencryptX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private AuthReencryptX509Cert() { + secret_ = com.google.protobuf.ByteString.EMPTY; + certificates_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AuthReencryptX509Cert( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + secret_ = input.readBytes(); + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) != 0)) { + certificates_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + certificates_.add(input.readBytes()); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); // C + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_descriptor; } - public static final int THRESHOLD_FIELD_NUMBER = 2; - private int threshold_; + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder.class); + } + + private int bitField0_; + public static final int SECRET_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString secret_; /** - * required sint32 threshold = 2; + * required bytes secret = 1; */ - public boolean hasThreshold() { + public boolean hasSecret() { return ((bitField0_ & 0x00000001) != 0); } /** - * required sint32 threshold = 2; + * required bytes secret = 1; */ - public int getThreshold() { - return threshold_; + public com.google.protobuf.ByteString getSecret() { + return secret_; + } + + public static final int CERTIFICATES_FIELD_NUMBER = 2; + private java.util.List certificates_; + /** + * repeated bytes certificates = 2; + */ + public java.util.List + getCertificatesList() { + return certificates_; + } + /** + * repeated bytes certificates = 2; + */ + public int getCertificatesCount() { + return certificates_.size(); + } + /** + * repeated bytes certificates = 2; + */ + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); } private byte memoizedIsInitialized = -1; @@ -4419,7 +9007,7 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasThreshold()) { + if (!hasSecret()) { memoizedIsInitialized = 0; return false; } @@ -4430,11 +9018,11 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - for (int i = 0; i < ca_.size(); i++) { - output.writeBytes(1, ca_.get(i)); - } if (((bitField0_ & 0x00000001) != 0)) { - output.writeSInt32(2, threshold_); + output.writeBytes(1, secret_); + } + for (int i = 0; i < certificates_.size(); i++) { + output.writeBytes(2, certificates_.get(i)); } unknownFields.writeTo(output); } @@ -4445,18 +9033,18 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, secret_); + } { int dataSize = 0; - for (int i = 0; i < ca_.size(); i++) { + for (int i = 0; i < certificates_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(ca_.get(i)); + .computeBytesSizeNoTag(certificates_.get(i)); } size += dataSize; - size += 1 * getCaList().size(); - } - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeSInt32Size(2, threshold_); + size += 1 * getCertificatesList().size(); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -4468,18 +9056,18 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthX509Cert)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert other = (ch.epfl.dedis.lib.proto.OCS.AuthX509Cert) obj; + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert other = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert) obj; - if (!getCaList() - .equals(other.getCaList())) return false; - if (hasThreshold() != other.hasThreshold()) return false; - if (hasThreshold()) { - if (getThreshold() - != other.getThreshold()) return false; + if (hasSecret() != other.hasSecret()) return false; + if (hasSecret()) { + if (!getSecret() + .equals(other.getSecret())) return false; } + if (!getCertificatesList() + .equals(other.getCertificatesList())) return false; if (!unknownFields.equals(other.unknownFields)) return false; return true; } @@ -4491,82 +9079,82 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (getCaCount() > 0) { - hash = (37 * hash) + CA_FIELD_NUMBER; - hash = (53 * hash) + getCaList().hashCode(); + if (hasSecret()) { + hash = (37 * hash) + SECRET_FIELD_NUMBER; + hash = (53 * hash) + getSecret().hashCode(); } - if (hasThreshold()) { - hash = (37 * hash) + THRESHOLD_FIELD_NUMBER; - hash = (53 * hash) + getThreshold(); + if (getCertificatesCount() > 0) { + hash = (37 * hash) + CERTIFICATES_FIELD_NUMBER; + hash = (53 * hash) + getCertificatesList().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -4579,7 +9167,7 @@ public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthX509Cert prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -4596,33 +9184,34 @@ protected Builder newBuilderForType( } /** *
-     * AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
-     * request. In its simplest form, it is simply the CA that will have to sign the
-     * certificates of the requesters.
-     * The Threshold indicates how many clients must have signed the request before it
-     * is accepted.
+     * AuthReencryptX509Cert holds the proof that at least a threshold number of clients
+     * accepted the reencryption.
+     * For each client, there must exist a certificate that can be verified by the
+     * CA certificate from PolicyX509Cert. Additionally, each client must sign the
+     * following message:
+     *   sha256( Secret | Ephemeral | Time )
      * 
* - * Protobuf type {@code ocs.AuthX509Cert} + * Protobuf type {@code ocs.AuthReencryptX509Cert} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.AuthX509Cert) - ch.epfl.dedis.lib.proto.OCS.AuthX509CertOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthReencryptX509Cert) + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthX509Cert_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -4640,9 +9229,9 @@ private void maybeForceBuilderInitialization() { @java.lang.Override public Builder clear() { super.clear(); - ca_ = java.util.Collections.emptyList(); + secret_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); - threshold_ = 0; + certificates_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); return this; } @@ -4650,17 +9239,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert build() { - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert build() { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -4668,19 +9257,19 @@ public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert buildPartial() { - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert result = new ch.epfl.dedis.lib.proto.OCS.AuthX509Cert(this); + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert result = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; - if (((bitField0_ & 0x00000001) != 0)) { - ca_ = java.util.Collections.unmodifiableList(ca_); - bitField0_ = (bitField0_ & ~0x00000001); - } - result.ca_ = ca_; - if (((from_bitField0_ & 0x00000002) != 0)) { - result.threshold_ = threshold_; + if (((from_bitField0_ & 0x00000001) != 0)) { to_bitField0_ |= 0x00000001; } + result.secret_ = secret_; + if (((bitField0_ & 0x00000002) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.certificates_ = certificates_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -4720,29 +9309,29 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthX509Cert) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthX509Cert)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthX509Cert other) { - if (other == ch.epfl.dedis.lib.proto.OCS.AuthX509Cert.getDefaultInstance()) return this; - if (!other.ca_.isEmpty()) { - if (ca_.isEmpty()) { - ca_ = other.ca_; - bitField0_ = (bitField0_ & ~0x00000001); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance()) return this; + if (other.hasSecret()) { + setSecret(other.getSecret()); + } + if (!other.certificates_.isEmpty()) { + if (certificates_.isEmpty()) { + certificates_ = other.certificates_; + bitField0_ = (bitField0_ & ~0x00000002); } else { - ensureCaIsMutable(); - ca_.addAll(other.ca_); + ensureCertificatesIsMutable(); + certificates_.addAll(other.certificates_); } onChanged(); } - if (other.hasThreshold()) { - setThreshold(other.getThreshold()); - } this.mergeUnknownFields(other.unknownFields); onChanged(); return this; @@ -4750,7 +9339,7 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthX509Cert other) { @java.lang.Override public final boolean isInitialized() { - if (!hasThreshold()) { + if (!hasSecret()) { return false; } return true; @@ -4761,11 +9350,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.AuthX509Cert parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthX509Cert) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -4776,135 +9365,110 @@ public Builder mergeFrom( } private int bitField0_; - private java.util.List ca_ = java.util.Collections.emptyList(); - private void ensureCaIsMutable() { - if (!((bitField0_ & 0x00000001) != 0)) { - ca_ = new java.util.ArrayList(ca_); - bitField0_ |= 0x00000001; - } - } - /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; - */ - public java.util.List - getCaList() { - return ((bitField0_ & 0x00000001) != 0) ? - java.util.Collections.unmodifiableList(ca_) : ca_; - } + private com.google.protobuf.ByteString secret_ = com.google.protobuf.ByteString.EMPTY; /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * required bytes secret = 1; */ - public int getCaCount() { - return ca_.size(); + public boolean hasSecret() { + return ((bitField0_ & 0x00000001) != 0); } /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * required bytes secret = 1; */ - public com.google.protobuf.ByteString getCa(int index) { - return ca_.get(index); + public com.google.protobuf.ByteString getSecret() { + return secret_; } /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * required bytes secret = 1; */ - public Builder setCa( - int index, com.google.protobuf.ByteString value) { + public Builder setSecret(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } - ensureCaIsMutable(); - ca_.set(index, value); + bitField0_ |= 0x00000001; + secret_ = value; onChanged(); return this; } /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * required bytes secret = 1; */ - public Builder addCa(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureCaIsMutable(); - ca_.add(value); + public Builder clearSecret() { + bitField0_ = (bitField0_ & ~0x00000001); + secret_ = getDefaultInstance().getSecret(); onChanged(); return this; } + + private java.util.List certificates_ = java.util.Collections.emptyList(); + private void ensureCertificatesIsMutable() { + if (!((bitField0_ & 0x00000002) != 0)) { + certificates_ = new java.util.ArrayList(certificates_); + bitField0_ |= 0x00000002; + } + } /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * repeated bytes certificates = 2; */ - public Builder addAllCa( - java.lang.Iterable values) { - ensureCaIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, ca_); - onChanged(); - return this; + public java.util.List + getCertificatesList() { + return ((bitField0_ & 0x00000002) != 0) ? + java.util.Collections.unmodifiableList(certificates_) : certificates_; } /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * repeated bytes certificates = 2; */ - public Builder clearCa() { - ca_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000001); - onChanged(); - return this; + public int getCertificatesCount() { + return certificates_.size(); + } + /** + * repeated bytes certificates = 2; + */ + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); } - - private int threshold_ ; /** - * required sint32 threshold = 2; + * repeated bytes certificates = 2; */ - public boolean hasThreshold() { - return ((bitField0_ & 0x00000002) != 0); + public Builder setCertificates( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCertificatesIsMutable(); + certificates_.set(index, value); + onChanged(); + return this; } /** - * required sint32 threshold = 2; + * repeated bytes certificates = 2; */ - public int getThreshold() { - return threshold_; + public Builder addCertificates(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCertificatesIsMutable(); + certificates_.add(value); + onChanged(); + return this; } /** - * required sint32 threshold = 2; + * repeated bytes certificates = 2; */ - public Builder setThreshold(int value) { - bitField0_ |= 0x00000002; - threshold_ = value; + public Builder addAllCertificates( + java.lang.Iterable values) { + ensureCertificatesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, certificates_); onChanged(); return this; } /** - * required sint32 threshold = 2; + * repeated bytes certificates = 2; */ - public Builder clearThreshold() { + public Builder clearCertificates() { + certificates_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); - threshold_ = 0; onChanged(); return this; } @@ -4921,96 +9485,95 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.AuthX509Cert) + // @@protoc_insertion_point(builder_scope:ocs.AuthReencryptX509Cert) } - // @@protoc_insertion_point(class_scope:ocs.AuthX509Cert) - private static final ch.epfl.dedis.lib.proto.OCS.AuthX509Cert DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthReencryptX509Cert) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthX509Cert(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert(); } - public static ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public AuthX509Cert parsePartialFrom( + public AuthReencryptX509Cert parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new AuthX509Cert(input, extensionRegistry); + return new AuthReencryptX509Cert(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthX509Cert getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface GrantOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.Grant) + public interface AuthReshareOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReshare) com.google.protobuf.MessageOrBuilder { /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ boolean hasByzcoin(); /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getByzcoin(); + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getByzcoin(); /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder getByzcoinOrBuilder(); + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder getByzcoinOrBuilder(); /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ boolean hasX509Cert(); /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getX509Cert(); + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getX509Cert(); /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder getX509CertOrBuilder(); + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder getX509CertOrBuilder(); } /** *
-   * Grant holds one of the possible grant proofs for a reencryption request. Each
-   * grant proof must hold the secret to be reencrypted, the ephemeral key, as well
-   * as the proof itself that the request is valid. For each of the authentication
-   * schemes, this proof will be different.
+   * AuthReshare holds the proof that at least a threshold number of clients accepted the
+   * request to reshare the secret key. The authentication must hold the new roster, as
+   * well as the proof that the new roster should be applied to a given OCS.
    * 
* - * Protobuf type {@code ocs.Grant} + * Protobuf type {@code ocs.AuthReshare} */ - public static final class Grant extends + public static final class AuthReshare extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.Grant) - GrantOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthReshare) + AuthReshareOrBuilder { private static final long serialVersionUID = 0L; - // Use Grant.newBuilder() to construct. - private Grant(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthReshare.newBuilder() to construct. + private AuthReshare(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private Grant() { + private AuthReshare() { } @java.lang.Override @@ -5018,7 +9581,7 @@ private Grant() { getUnknownFields() { return this.unknownFields; } - private Grant( + private AuthReshare( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -5038,11 +9601,11 @@ private Grant( done = true; break; case 10: { - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder subBuilder = null; + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder subBuilder = null; if (((bitField0_ & 0x00000001) != 0)) { subBuilder = byzcoin_.toBuilder(); } - byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.parser(), extensionRegistry); + byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.parser(), extensionRegistry); if (subBuilder != null) { subBuilder.mergeFrom(byzcoin_); byzcoin_ = subBuilder.buildPartial(); @@ -5051,11 +9614,11 @@ private Grant( break; } case 18: { - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder subBuilder = null; + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder subBuilder = null; if (((bitField0_ & 0x00000002) != 0)) { subBuilder = x509Cert_.toBuilder(); } - x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.parser(), extensionRegistry); + x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.parser(), extensionRegistry); if (subBuilder != null) { subBuilder.mergeFrom(x509Cert_); x509Cert_ = subBuilder.buildPartial(); @@ -5084,58 +9647,58 @@ private Grant( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Grant_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Grant_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.Grant.class, ch.epfl.dedis.lib.proto.OCS.Grant.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReshare.class, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder.class); } private int bitField0_; public static final int BYZCOIN_FIELD_NUMBER = 1; - private ch.epfl.dedis.lib.proto.OCS.GrantByzCoin byzcoin_; + private ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin byzcoin_; /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ public boolean hasByzcoin() { return ((bitField0_ & 0x00000001) != 0); } /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getByzcoin() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance() : byzcoin_; + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getByzcoin() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; } /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder getByzcoinOrBuilder() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance() : byzcoin_; + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder getByzcoinOrBuilder() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; } public static final int X509CERT_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.OCS.GrantX509Cert x509Cert_; + private ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert x509Cert_; /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ public boolean hasX509Cert() { return ((bitField0_ & 0x00000002) != 0); } /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getX509Cert() { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance() : x509Cert_; + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getX509Cert() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; } /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder getX509CertOrBuilder() { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance() : x509Cert_; + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder getX509CertOrBuilder() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; } private byte memoizedIsInitialized = -1; @@ -5151,12 +9714,6 @@ public final boolean isInitialized() { return false; } } - if (hasX509Cert()) { - if (!getX509Cert().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } - } memoizedIsInitialized = 1; return true; } @@ -5197,10 +9754,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Grant)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshare)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.Grant other = (ch.epfl.dedis.lib.proto.OCS.Grant) obj; + ch.epfl.dedis.lib.proto.OCS.AuthReshare other = (ch.epfl.dedis.lib.proto.OCS.AuthReshare) obj; if (hasByzcoin() != other.hasByzcoin()) return false; if (hasByzcoin()) { @@ -5236,69 +9793,69 @@ public int hashCode() { return hash; } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -5311,7 +9868,7 @@ public static ch.epfl.dedis.lib.proto.OCS.Grant parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Grant prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReshare prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -5328,32 +9885,31 @@ protected Builder newBuilderForType( } /** *
-     * Grant holds one of the possible grant proofs for a reencryption request. Each
-     * grant proof must hold the secret to be reencrypted, the ephemeral key, as well
-     * as the proof itself that the request is valid. For each of the authentication
-     * schemes, this proof will be different.
+     * AuthReshare holds the proof that at least a threshold number of clients accepted the
+     * request to reshare the secret key. The authentication must hold the new roster, as
+     * well as the proof that the new roster should be applied to a given OCS.
      * 
* - * Protobuf type {@code ocs.Grant} + * Protobuf type {@code ocs.AuthReshare} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.Grant) - ch.epfl.dedis.lib.proto.OCS.GrantOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthReshare) + ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Grant_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Grant_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.Grant.class, ch.epfl.dedis.lib.proto.OCS.Grant.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReshare.class, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.Grant.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReshare.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -5391,17 +9947,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Grant_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Grant getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshare getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Grant build() { - ch.epfl.dedis.lib.proto.OCS.Grant result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshare build() { + ch.epfl.dedis.lib.proto.OCS.AuthReshare result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -5409,8 +9965,8 @@ public ch.epfl.dedis.lib.proto.OCS.Grant build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Grant buildPartial() { - ch.epfl.dedis.lib.proto.OCS.Grant result = new ch.epfl.dedis.lib.proto.OCS.Grant(this); + public ch.epfl.dedis.lib.proto.OCS.AuthReshare buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReshare result = new ch.epfl.dedis.lib.proto.OCS.AuthReshare(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -5468,16 +10024,16 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.Grant) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Grant)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshare) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReshare)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Grant other) { - if (other == ch.epfl.dedis.lib.proto.OCS.Grant.getDefaultInstance()) return this; + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReshare other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance()) return this; if (other.hasByzcoin()) { mergeByzcoin(other.getByzcoin()); } @@ -5496,11 +10052,6 @@ public final boolean isInitialized() { return false; } } - if (hasX509Cert()) { - if (!getX509Cert().isInitialized()) { - return false; - } - } return true; } @@ -5509,11 +10060,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.Grant parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AuthReshare parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Grant) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReshare) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -5524,29 +10075,29 @@ public Builder mergeFrom( } private int bitField0_; - private ch.epfl.dedis.lib.proto.OCS.GrantByzCoin byzcoin_; + private ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin byzcoin_; private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin, ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder> byzcoinBuilder_; + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder> byzcoinBuilder_; /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ public boolean hasByzcoin() { return ((bitField0_ & 0x00000001) != 0); } /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getByzcoin() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getByzcoin() { if (byzcoinBuilder_ == null) { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance() : byzcoin_; + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; } else { return byzcoinBuilder_.getMessage(); } } /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin value) { + public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin value) { if (byzcoinBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -5560,10 +10111,10 @@ public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin value) { return this; } /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ public Builder setByzcoin( - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder builderForValue) { + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder builderForValue) { if (byzcoinBuilder_ == null) { byzcoin_ = builderForValue.build(); onChanged(); @@ -5574,15 +10125,15 @@ public Builder setByzcoin( return this; } /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin value) { + public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin value) { if (byzcoinBuilder_ == null) { if (((bitField0_ & 0x00000001) != 0) && byzcoin_ != null && - byzcoin_ != ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance()) { + byzcoin_ != ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance()) { byzcoin_ = - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); } else { byzcoin_ = value; } @@ -5594,7 +10145,7 @@ public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin value) { return this; } /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ public Builder clearByzcoin() { if (byzcoinBuilder_ == null) { @@ -5607,33 +10158,33 @@ public Builder clearByzcoin() { return this; } /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder getByzcoinBuilder() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder getByzcoinBuilder() { bitField0_ |= 0x00000001; onChanged(); return getByzcoinFieldBuilder().getBuilder(); } /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder getByzcoinOrBuilder() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder getByzcoinOrBuilder() { if (byzcoinBuilder_ != null) { return byzcoinBuilder_.getMessageOrBuilder(); } else { return byzcoin_ == null ? - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance() : byzcoin_; + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; } } /** - * optional .ocs.GrantByzCoin byzcoin = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin, ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder> + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder> getByzcoinFieldBuilder() { if (byzcoinBuilder_ == null) { byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin, ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder>( + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder>( getByzcoin(), getParentForChildren(), isClean()); @@ -5642,29 +10193,29 @@ public ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder getByzcoinOrBuilder() { return byzcoinBuilder_; } - private ch.epfl.dedis.lib.proto.OCS.GrantX509Cert x509Cert_; + private ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert x509Cert_; private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert, ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder> x509CertBuilder_; + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder> x509CertBuilder_; /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ public boolean hasX509Cert() { return ((bitField0_ & 0x00000002) != 0); } /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getX509Cert() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getX509Cert() { if (x509CertBuilder_ == null) { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance() : x509Cert_; + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; } else { return x509CertBuilder_.getMessage(); } } /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public Builder setX509Cert(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert value) { + public Builder setX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert value) { if (x509CertBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -5678,10 +10229,10 @@ public Builder setX509Cert(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert value) { return this; } /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ public Builder setX509Cert( - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder builderForValue) { + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder builderForValue) { if (x509CertBuilder_ == null) { x509Cert_ = builderForValue.build(); onChanged(); @@ -5692,15 +10243,15 @@ public Builder setX509Cert( return this; } /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert value) { + public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert value) { if (x509CertBuilder_ == null) { if (((bitField0_ & 0x00000002) != 0) && x509Cert_ != null && - x509Cert_ != ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance()) { + x509Cert_ != ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance()) { x509Cert_ = - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); } else { x509Cert_ = value; } @@ -5712,7 +10263,7 @@ public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert value) { return this; } /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ public Builder clearX509Cert() { if (x509CertBuilder_ == null) { @@ -5725,33 +10276,33 @@ public Builder clearX509Cert() { return this; } /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder getX509CertBuilder() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder getX509CertBuilder() { bitField0_ |= 0x00000002; onChanged(); return getX509CertFieldBuilder().getBuilder(); } /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder getX509CertOrBuilder() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder getX509CertOrBuilder() { if (x509CertBuilder_ != null) { return x509CertBuilder_.getMessageOrBuilder(); } else { return x509Cert_ == null ? - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance() : x509Cert_; + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; } } /** - * optional .ocs.GrantX509Cert x509cert = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert, ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder> + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder> getX509CertFieldBuilder() { if (x509CertBuilder_ == null) { x509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert, ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder>( + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder>( getX509Cert(), getParentForChildren(), isClean()); @@ -5772,105 +10323,79 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.Grant) + // @@protoc_insertion_point(builder_scope:ocs.AuthReshare) } - // @@protoc_insertion_point(class_scope:ocs.Grant) - private static final ch.epfl.dedis.lib.proto.OCS.Grant DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthReshare) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReshare DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Grant(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReshare(); } - public static ch.epfl.dedis.lib.proto.OCS.Grant getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public Grant parsePartialFrom( + public AuthReshare parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new Grant(input, extensionRegistry); + return new AuthReshare(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Grant getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshare getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface GrantByzCoinOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.GrantByzCoin) + public interface AuthReshareByzCoinOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReshareByzCoin) com.google.protobuf.MessageOrBuilder { /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required bytes write = 1; - */ - boolean hasWrite(); - /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required bytes write = 1; - */ - com.google.protobuf.ByteString getWrite(); - - /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required bytes read = 2; + * required bytes reshare = 1; */ - boolean hasRead(); + boolean hasReshare(); /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required bytes read = 2; + * required bytes reshare = 1; */ - com.google.protobuf.ByteString getRead(); + com.google.protobuf.ByteString getReshare(); } /** *
-   * GrantByzCoin holds the proof of the write instance, holding the secret itself.
-   * The proof of the read instance holds the ephemeral key. Both proofs can be
-   * verified using one of the stored ByzCoinIDs.
+   * AuthReshareByzCoin holds the byzcoin-proof that contains the latest OCS-instance
+   * which includes the roster. The OCS-nodes will make sure that the version of the
+   * OCS-instance is bigger than the current version.
    * 
* - * Protobuf type {@code ocs.GrantByzCoin} + * Protobuf type {@code ocs.AuthReshareByzCoin} */ - public static final class GrantByzCoin extends + public static final class AuthReshareByzCoin extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.GrantByzCoin) - GrantByzCoinOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthReshareByzCoin) + AuthReshareByzCoinOrBuilder { private static final long serialVersionUID = 0L; - // Use GrantByzCoin.newBuilder() to construct. - private GrantByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthReshareByzCoin.newBuilder() to construct. + private AuthReshareByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private GrantByzCoin() { - write_ = com.google.protobuf.ByteString.EMPTY; - read_ = com.google.protobuf.ByteString.EMPTY; + private AuthReshareByzCoin() { + reshare_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -5878,7 +10403,7 @@ private GrantByzCoin() { getUnknownFields() { return this.unknownFields; } - private GrantByzCoin( + private AuthReshareByzCoin( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -5899,12 +10424,7 @@ private GrantByzCoin( break; case 10: { bitField0_ |= 0x00000001; - write_ = input.readBytes(); - break; - } - case 18: { - bitField0_ |= 0x00000002; - read_ = input.readBytes(); + reshare_ = input.readBytes(); break; } default: { @@ -5928,62 +10448,31 @@ private GrantByzCoin( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantByzCoin_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.class, ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder.class); } private int bitField0_; - public static final int WRITE_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString write_; + public static final int RESHARE_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString reshare_; /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required bytes write = 1; + * required bytes reshare = 1; */ - public boolean hasWrite() { + public boolean hasReshare() { return ((bitField0_ & 0x00000001) != 0); } /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required bytes write = 1; - */ - public com.google.protobuf.ByteString getWrite() { - return write_; - } - - public static final int READ_FIELD_NUMBER = 2; - private com.google.protobuf.ByteString read_; - /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required bytes read = 2; - */ - public boolean hasRead() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required bytes read = 2; + * required bytes reshare = 1; */ - public com.google.protobuf.ByteString getRead() { - return read_; + public com.google.protobuf.ByteString getReshare() { + return reshare_; } private byte memoizedIsInitialized = -1; @@ -5993,11 +10482,7 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasWrite()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasRead()) { + if (!hasReshare()) { memoizedIsInitialized = 0; return false; } @@ -6009,10 +10494,7 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, write_); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeBytes(2, read_); + output.writeBytes(1, reshare_); } unknownFields.writeTo(output); } @@ -6025,11 +10507,7 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, write_); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(2, read_); + .computeBytesSize(1, reshare_); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -6041,20 +10519,15 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.GrantByzCoin)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin other = (ch.epfl.dedis.lib.proto.OCS.GrantByzCoin) obj; + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin other = (ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin) obj; - if (hasWrite() != other.hasWrite()) return false; - if (hasWrite()) { - if (!getWrite() - .equals(other.getWrite())) return false; - } - if (hasRead() != other.hasRead()) return false; - if (hasRead()) { - if (!getRead() - .equals(other.getRead())) return false; + if (hasReshare() != other.hasReshare()) return false; + if (hasReshare()) { + if (!getReshare() + .equals(other.getReshare())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -6067,82 +10540,78 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasWrite()) { - hash = (37 * hash) + WRITE_FIELD_NUMBER; - hash = (53 * hash) + getWrite().hashCode(); - } - if (hasRead()) { - hash = (37 * hash) + READ_FIELD_NUMBER; - hash = (53 * hash) + getRead().hashCode(); + if (hasReshare()) { + hash = (37 * hash) + RESHARE_FIELD_NUMBER; + hash = (53 * hash) + getReshare().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -6155,7 +10624,7 @@ public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -6172,31 +10641,31 @@ protected Builder newBuilderForType( } /** *
-     * GrantByzCoin holds the proof of the write instance, holding the secret itself.
-     * The proof of the read instance holds the ephemeral key. Both proofs can be
-     * verified using one of the stored ByzCoinIDs.
+     * AuthReshareByzCoin holds the byzcoin-proof that contains the latest OCS-instance
+     * which includes the roster. The OCS-nodes will make sure that the version of the
+     * OCS-instance is bigger than the current version.
      * 
* - * Protobuf type {@code ocs.GrantByzCoin} + * Protobuf type {@code ocs.AuthReshareByzCoin} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.GrantByzCoin) - ch.epfl.dedis.lib.proto.OCS.GrantByzCoinOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthReshareByzCoin) + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantByzCoin_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.class, ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -6214,27 +10683,25 @@ private void maybeForceBuilderInitialization() { @java.lang.Override public Builder clear() { super.clear(); - write_ = com.google.protobuf.ByteString.EMPTY; + reshare_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); - read_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000002); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin build() { - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin build() { + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -6242,18 +10709,14 @@ public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin buildPartial() { - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin result = new ch.epfl.dedis.lib.proto.OCS.GrantByzCoin(this); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin result = new ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { to_bitField0_ |= 0x00000001; } - result.write_ = write_; - if (((from_bitField0_ & 0x00000002) != 0)) { - to_bitField0_ |= 0x00000002; - } - result.read_ = read_; + result.reshare_ = reshare_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -6293,156 +10756,83 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.GrantByzCoin) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.GrantByzCoin)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.GrantByzCoin other) { - if (other == ch.epfl.dedis.lib.proto.OCS.GrantByzCoin.getDefaultInstance()) return this; - if (other.hasWrite()) { - setWrite(other.getWrite()); - } - if (other.hasRead()) { - setRead(other.getRead()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - if (!hasWrite()) { - return false; - } - if (!hasRead()) { - return false; - } - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.GrantByzCoin parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.GrantByzCoin) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - private com.google.protobuf.ByteString write_ = com.google.protobuf.ByteString.EMPTY; - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required bytes write = 1; - */ - public boolean hasWrite() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required bytes write = 1; - */ - public com.google.protobuf.ByteString getWrite() { - return write_; - } - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required bytes write = 1; - */ - public Builder setWrite(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - write_ = value; + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance()) return this; + if (other.hasReshare()) { + setReshare(other.getReshare()); + } + this.mergeUnknownFields(other.unknownFields); onChanged(); return this; } - /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required bytes write = 1; - */ - public Builder clearWrite() { - bitField0_ = (bitField0_ & ~0x00000001); - write_ = getDefaultInstance().getWrite(); - onChanged(); + + @java.lang.Override + public final boolean isInitialized() { + if (!hasReshare()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } return this; } + private int bitField0_; - private com.google.protobuf.ByteString read_ = com.google.protobuf.ByteString.EMPTY; + private com.google.protobuf.ByteString reshare_ = com.google.protobuf.ByteString.EMPTY; /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required bytes read = 2; + * required bytes reshare = 1; */ - public boolean hasRead() { - return ((bitField0_ & 0x00000002) != 0); + public boolean hasReshare() { + return ((bitField0_ & 0x00000001) != 0); } /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required bytes read = 2; + * required bytes reshare = 1; */ - public com.google.protobuf.ByteString getRead() { - return read_; + public com.google.protobuf.ByteString getReshare() { + return reshare_; } /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required bytes read = 2; + * required bytes reshare = 1; */ - public Builder setRead(com.google.protobuf.ByteString value) { + public Builder setReshare(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } - bitField0_ |= 0x00000002; - read_ = value; + bitField0_ |= 0x00000001; + reshare_ = value; onChanged(); return this; } /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required bytes read = 2; + * required bytes reshare = 1; */ - public Builder clearRead() { - bitField0_ = (bitField0_ & ~0x00000002); - read_ = getDefaultInstance().getRead(); + public Builder clearReshare() { + bitField0_ = (bitField0_ & ~0x00000001); + reshare_ = getDefaultInstance().getReshare(); onChanged(); return this; } @@ -6459,95 +10849,80 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.GrantByzCoin) + // @@protoc_insertion_point(builder_scope:ocs.AuthReshareByzCoin) } - // @@protoc_insertion_point(class_scope:ocs.GrantByzCoin) - private static final ch.epfl.dedis.lib.proto.OCS.GrantByzCoin DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthReshareByzCoin) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.GrantByzCoin(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin(); } - public static ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public GrantByzCoin parsePartialFrom( + public AuthReshareByzCoin parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new GrantByzCoin(input, extensionRegistry); + return new AuthReshareByzCoin(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.GrantByzCoin getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface GrantX509CertOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.GrantX509Cert) + public interface AuthReshareX509CertOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReshareX509Cert) com.google.protobuf.MessageOrBuilder { /** - * required bytes secret = 1; - */ - boolean hasSecret(); - /** - * required bytes secret = 1; - */ - com.google.protobuf.ByteString getSecret(); - - /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ java.util.List getCertificatesList(); /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ int getCertificatesCount(); /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ com.google.protobuf.ByteString getCertificates(int index); } /** *
-   * GrantX509Cert holds the proof that at least a threshold number of clients
-   * accepted the reencryption.
-   * For each client, there must exist a certificate that can be verified by the
-   * CA certificate from AuthX509Cert. Additionally, each client must sign the
-   * following message:
-   *   sha256( Secret | Ephemeral | Time )
+   * AuthReshareX509Cert holds the X509 proof that the new roster is valid.
    * 
* - * Protobuf type {@code ocs.GrantX509Cert} + * Protobuf type {@code ocs.AuthReshareX509Cert} */ - public static final class GrantX509Cert extends + public static final class AuthReshareX509Cert extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.GrantX509Cert) - GrantX509CertOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthReshareX509Cert) + AuthReshareX509CertOrBuilder { private static final long serialVersionUID = 0L; - // Use GrantX509Cert.newBuilder() to construct. - private GrantX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthReshareX509Cert.newBuilder() to construct. + private AuthReshareX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private GrantX509Cert() { - secret_ = com.google.protobuf.ByteString.EMPTY; + private AuthReshareX509Cert() { certificates_ = java.util.Collections.emptyList(); } @@ -6556,7 +10931,7 @@ private GrantX509Cert() { getUnknownFields() { return this.unknownFields; } - private GrantX509Cert( + private AuthReshareX509Cert( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -6576,14 +10951,9 @@ private GrantX509Cert( done = true; break; case 10: { - bitField0_ |= 0x00000001; - secret_ = input.readBytes(); - break; - } - case 18: { - if (!((mutable_bitField0_ & 0x00000002) != 0)) { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { certificates_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000002; + mutable_bitField0_ |= 0x00000001; } certificates_.add(input.readBytes()); break; @@ -6603,7 +10973,7 @@ private GrantX509Cert( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { - if (((mutable_bitField0_ & 0x00000002) != 0)) { + if (((mutable_bitField0_ & 0x00000001) != 0)) { certificates_ = java.util.Collections.unmodifiableList(certificates_); // C } this.unknownFields = unknownFields.build(); @@ -6612,50 +10982,34 @@ private GrantX509Cert( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantX509Cert_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.class, ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder.class); - } - - private int bitField0_; - public static final int SECRET_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString secret_; - /** - * required bytes secret = 1; - */ - public boolean hasSecret() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * required bytes secret = 1; - */ - public com.google.protobuf.ByteString getSecret() { - return secret_; + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder.class); } - public static final int CERTIFICATES_FIELD_NUMBER = 2; + public static final int CERTIFICATES_FIELD_NUMBER = 1; private java.util.List certificates_; /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ public java.util.List getCertificatesList() { return certificates_; } /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ public int getCertificatesCount() { return certificates_.size(); } /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ public com.google.protobuf.ByteString getCertificates(int index) { return certificates_.get(index); @@ -6668,10 +11022,6 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasSecret()) { - memoizedIsInitialized = 0; - return false; - } memoizedIsInitialized = 1; return true; } @@ -6679,11 +11029,8 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, secret_); - } for (int i = 0; i < certificates_.size(); i++) { - output.writeBytes(2, certificates_.get(i)); + output.writeBytes(1, certificates_.get(i)); } unknownFields.writeTo(output); } @@ -6694,10 +11041,6 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, secret_); - } { int dataSize = 0; for (int i = 0; i < certificates_.size(); i++) { @@ -6717,16 +11060,11 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.GrantX509Cert)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert other = (ch.epfl.dedis.lib.proto.OCS.GrantX509Cert) obj; + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert other = (ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert) obj; - if (hasSecret() != other.hasSecret()) return false; - if (hasSecret()) { - if (!getSecret() - .equals(other.getSecret())) return false; - } if (!getCertificatesList() .equals(other.getCertificatesList())) return false; if (!unknownFields.equals(other.unknownFields)) return false; @@ -6740,10 +11078,6 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasSecret()) { - hash = (37 * hash) + SECRET_FIELD_NUMBER; - hash = (53 * hash) + getSecret().hashCode(); - } if (getCertificatesCount() > 0) { hash = (37 * hash) + CERTIFICATES_FIELD_NUMBER; hash = (53 * hash) + getCertificatesList().hashCode(); @@ -6753,69 +11087,69 @@ public int hashCode() { return hash; } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -6828,7 +11162,7 @@ public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -6845,34 +11179,29 @@ protected Builder newBuilderForType( } /** *
-     * GrantX509Cert holds the proof that at least a threshold number of clients
-     * accepted the reencryption.
-     * For each client, there must exist a certificate that can be verified by the
-     * CA certificate from AuthX509Cert. Additionally, each client must sign the
-     * following message:
-     *   sha256( Secret | Ephemeral | Time )
+     * AuthReshareX509Cert holds the X509 proof that the new roster is valid.
      * 
* - * Protobuf type {@code ocs.GrantX509Cert} + * Protobuf type {@code ocs.AuthReshareX509Cert} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.GrantX509Cert) - ch.epfl.dedis.lib.proto.OCS.GrantX509CertOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthReshareX509Cert) + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantX509Cert_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.class, ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -6890,27 +11219,25 @@ private void maybeForceBuilderInitialization() { @java.lang.Override public Builder clear() { super.clear(); - secret_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000001); certificates_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000002); + bitField0_ = (bitField0_ & ~0x00000001); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GrantX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert build() { - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert build() { + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -6918,20 +11245,14 @@ public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert buildPartial() { - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert result = new ch.epfl.dedis.lib.proto.OCS.GrantX509Cert(this); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert result = new ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert(this); int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) != 0)) { - to_bitField0_ |= 0x00000001; - } - result.secret_ = secret_; - if (((bitField0_ & 0x00000002) != 0)) { + if (((bitField0_ & 0x00000001) != 0)) { certificates_ = java.util.Collections.unmodifiableList(certificates_); - bitField0_ = (bitField0_ & ~0x00000002); + bitField0_ = (bitField0_ & ~0x00000001); } result.certificates_ = certificates_; - result.bitField0_ = to_bitField0_; onBuilt(); return result; } @@ -6970,23 +11291,20 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.GrantX509Cert) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.GrantX509Cert)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert other) { - if (other == ch.epfl.dedis.lib.proto.OCS.GrantX509Cert.getDefaultInstance()) return this; - if (other.hasSecret()) { - setSecret(other.getSecret()); - } + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance()) return this; if (!other.certificates_.isEmpty()) { if (certificates_.isEmpty()) { certificates_ = other.certificates_; - bitField0_ = (bitField0_ & ~0x00000002); + bitField0_ = (bitField0_ & ~0x00000001); } else { ensureCertificatesIsMutable(); certificates_.addAll(other.certificates_); @@ -7000,9 +11318,6 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.GrantX509Cert other) { @java.lang.Override public final boolean isInitialized() { - if (!hasSecret()) { - return false; - } return true; } @@ -7011,11 +11326,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.GrantX509Cert parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.GrantX509Cert) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -7026,70 +11341,35 @@ public Builder mergeFrom( } private int bitField0_; - private com.google.protobuf.ByteString secret_ = com.google.protobuf.ByteString.EMPTY; - /** - * required bytes secret = 1; - */ - public boolean hasSecret() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * required bytes secret = 1; - */ - public com.google.protobuf.ByteString getSecret() { - return secret_; - } - /** - * required bytes secret = 1; - */ - public Builder setSecret(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - secret_ = value; - onChanged(); - return this; - } - /** - * required bytes secret = 1; - */ - public Builder clearSecret() { - bitField0_ = (bitField0_ & ~0x00000001); - secret_ = getDefaultInstance().getSecret(); - onChanged(); - return this; - } - private java.util.List certificates_ = java.util.Collections.emptyList(); private void ensureCertificatesIsMutable() { - if (!((bitField0_ & 0x00000002) != 0)) { + if (!((bitField0_ & 0x00000001) != 0)) { certificates_ = new java.util.ArrayList(certificates_); - bitField0_ |= 0x00000002; + bitField0_ |= 0x00000001; } } /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ public java.util.List getCertificatesList() { - return ((bitField0_ & 0x00000002) != 0) ? + return ((bitField0_ & 0x00000001) != 0) ? java.util.Collections.unmodifiableList(certificates_) : certificates_; } /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ public int getCertificatesCount() { return certificates_.size(); } /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ public com.google.protobuf.ByteString getCertificates(int index) { return certificates_.get(index); } /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ public Builder setCertificates( int index, com.google.protobuf.ByteString value) { @@ -7102,7 +11382,7 @@ public Builder setCertificates( return this; } /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ public Builder addCertificates(com.google.protobuf.ByteString value) { if (value == null) { @@ -7114,7 +11394,7 @@ public Builder addCertificates(com.google.protobuf.ByteString value) { return this; } /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ public Builder addAllCertificates( java.lang.Iterable values) { @@ -7125,11 +11405,11 @@ public Builder addAllCertificates( return this; } /** - * repeated bytes certificates = 2; + * repeated bytes certificates = 1; */ public Builder clearCertificates() { certificates_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000002); + bitField0_ = (bitField0_ & ~0x00000001); onChanged(); return this; } @@ -7146,41 +11426,41 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.GrantX509Cert) + // @@protoc_insertion_point(builder_scope:ocs.AuthReshareX509Cert) } - // @@protoc_insertion_point(class_scope:ocs.GrantX509Cert) - private static final ch.epfl.dedis.lib.proto.OCS.GrantX509Cert DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthReshareX509Cert) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.GrantX509Cert(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert(); } - public static ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public GrantX509Cert parsePartialFrom( + public AuthReshareX509Cert parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new GrantX509Cert(input, extensionRegistry); + return new AuthReshareX509Cert(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -7207,35 +11487,65 @@ public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getDefaultInstanceForType() { com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_ocs_ReencryptReply_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor - internal_static_ocs_Auth_descriptor; + internal_static_ocs_Reshare_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_Reshare_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_ReshareReply_descriptor; private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_ocs_Auth_fieldAccessorTable; + internal_static_ocs_ReshareReply_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor - internal_static_ocs_AuthByzCoin_descriptor; + internal_static_ocs_PolicyOCS_descriptor; private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_ocs_AuthByzCoin_fieldAccessorTable; + internal_static_ocs_PolicyOCS_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor - internal_static_ocs_AuthX509Cert_descriptor; + internal_static_ocs_Policy_descriptor; private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_ocs_AuthX509Cert_fieldAccessorTable; + internal_static_ocs_Policy_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor - internal_static_ocs_Grant_descriptor; + internal_static_ocs_PolicyByzCoin_descriptor; private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_ocs_Grant_fieldAccessorTable; + internal_static_ocs_PolicyByzCoin_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor - internal_static_ocs_GrantByzCoin_descriptor; + internal_static_ocs_PolicyX509Cert_descriptor; private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_ocs_GrantByzCoin_fieldAccessorTable; + internal_static_ocs_PolicyX509Cert_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor - internal_static_ocs_GrantX509Cert_descriptor; + internal_static_ocs_AuthReencrypt_descriptor; private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_ocs_GrantX509Cert_fieldAccessorTable; + internal_static_ocs_AuthReencrypt_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AuthReencryptByzCoin_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AuthReencryptByzCoin_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AuthReencryptX509Cert_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AuthReencryptX509Cert_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AuthReshare_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AuthReshare_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AuthReshareByzCoin_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AuthReshareByzCoin_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AuthReshareX509Cert_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AuthReshareX509Cert_fieldAccessorTable; public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { @@ -7245,22 +11555,33 @@ public ch.epfl.dedis.lib.proto.OCS.GrantX509Cert getDefaultInstanceForType() { descriptor; static { java.lang.String[] descriptorData = { - "\n\tocs.proto\022\003ocs\032\nonet.proto\"L\n\tCreateOC" + - "S\022\034\n\006roster\030\001 \002(\0132\014.onet.Roster\022!\n\016authe" + - "ntication\030\002 \002(\0132\t.ocs.Auth\"(\n\016CreateOCSR" + - "eply\022\t\n\001x\030\001 \002(\014\022\013\n\003sig\030\002 \002(\014\"1\n\tReencryp" + - "t\022\t\n\001x\030\001 \002(\014\022\031\n\005grant\030\002 \002(\0132\n.ocs.Grant\"" + - "\036\n\016ReencryptReply\022\014\n\004xhat\030\001 \002(\014\"R\n\004Auth\022" + - "!\n\007byzcoin\030\001 \001(\0132\020.ocs.AuthByzCoin\022\'\n\014au" + - "thx509cert\030\002 \001(\0132\021.ocs.AuthX509Cert\"-\n\013A" + - "uthByzCoin\022\021\n\tbyzcoinid\030\001 \002(\014\022\013\n\003ttl\030\002 \002" + - "(\004\"-\n\014AuthX509Cert\022\n\n\002ca\030\001 \003(\014\022\021\n\tthresh" + - "old\030\002 \002(\021\"Q\n\005Grant\022\"\n\007byzcoin\030\001 \001(\0132\021.oc" + - "s.GrantByzCoin\022$\n\010x509cert\030\002 \001(\0132\022.ocs.G" + - "rantX509Cert\"+\n\014GrantByzCoin\022\r\n\005write\030\001 " + - "\002(\014\022\014\n\004read\030\002 \002(\014\"5\n\rGrantX509Cert\022\016\n\006se" + - "cret\030\001 \002(\014\022\024\n\014certificates\030\002 \003(\014B\036\n\027ch.e" + - "pfl.dedis.lib.protoB\003OCS" + "\n\tocs.proto\022\003ocs\032\nonet.proto\"F\n\tCreateOC" + + "S\022\034\n\006roster\030\001 \002(\0132\014.onet.Roster\022\033\n\006polic" + + "y\030\002 \002(\0132\013.ocs.Policy\"(\n\016CreateOCSReply\022\t" + + "\n\001x\030\001 \002(\014\022\013\n\003sig\030\002 \002(\014\"8\n\tReencrypt\022\t\n\001x" + + "\030\001 \002(\014\022 \n\004auth\030\002 \002(\0132\022.ocs.AuthReencrypt" + + "\"\036\n\016ReencryptReply\022\014\n\004xhat\030\001 \002(\014\"U\n\007Resh" + + "are\022\t\n\001x\030\001 \002(\014\022\037\n\tnewroster\030\002 \002(\0132\014.onet" + + ".Roster\022\036\n\004auth\030\003 \002(\0132\020.ocs.AuthReshare\"" + + "\033\n\014ReshareReply\022\013\n\003sig\030\001 \002(\014\"U\n\tPolicyOC" + + "S\022$\n\017policyreencrypt\030\001 \002(\0132\013.ocs.Policy\022" + + "\"\n\rpolicyreshare\030\002 \002(\0132\013.ocs.Policy\"X\n\006P" + + "olicy\022#\n\007byzcoin\030\001 \001(\0132\022.ocs.PolicyByzCo" + + "in\022)\n\014authx509cert\030\002 \001(\0132\023.ocs.PolicyX50" + + "9Cert\"/\n\rPolicyByzCoin\022\021\n\tbyzcoinid\030\001 \002(" + + "\014\022\013\n\003ttl\030\002 \002(\004\"/\n\016PolicyX509Cert\022\n\n\002ca\030\001" + + " \003(\014\022\021\n\tthreshold\030\002 \002(\021\"i\n\rAuthReencrypt" + + "\022*\n\007byzcoin\030\001 \001(\0132\031.ocs.AuthReencryptByz" + + "Coin\022,\n\010x509cert\030\002 \001(\0132\032.ocs.AuthReencry" + + "ptX509Cert\"3\n\024AuthReencryptByzCoin\022\r\n\005wr" + + "ite\030\001 \002(\014\022\014\n\004read\030\002 \002(\014\"=\n\025AuthReencrypt" + + "X509Cert\022\016\n\006secret\030\001 \002(\014\022\024\n\014certificates" + + "\030\002 \003(\014\"c\n\013AuthReshare\022(\n\007byzcoin\030\001 \001(\0132\027" + + ".ocs.AuthReshareByzCoin\022*\n\010x509cert\030\002 \001(" + + "\0132\030.ocs.AuthReshareX509Cert\"%\n\022AuthResha" + + "reByzCoin\022\017\n\007reshare\030\001 \002(\014\"+\n\023AuthReshar" + + "eX509Cert\022\024\n\014certificates\030\001 \003(\014B\036\n\027ch.ep" + + "fl.dedis.lib.protoB\003OCS" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { @@ -7280,7 +11601,7 @@ public com.google.protobuf.ExtensionRegistry assignDescriptors( internal_static_ocs_CreateOCS_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_CreateOCS_descriptor, - new java.lang.String[] { "Roster", "Authentication", }); + new java.lang.String[] { "Roster", "Policy", }); internal_static_ocs_CreateOCSReply_descriptor = getDescriptor().getMessageTypes().get(1); internal_static_ocs_CreateOCSReply_fieldAccessorTable = new @@ -7292,49 +11613,85 @@ public com.google.protobuf.ExtensionRegistry assignDescriptors( internal_static_ocs_Reencrypt_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_Reencrypt_descriptor, - new java.lang.String[] { "X", "Grant", }); + new java.lang.String[] { "X", "Auth", }); internal_static_ocs_ReencryptReply_descriptor = getDescriptor().getMessageTypes().get(3); internal_static_ocs_ReencryptReply_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_ReencryptReply_descriptor, new java.lang.String[] { "Xhat", }); - internal_static_ocs_Auth_descriptor = + internal_static_ocs_Reshare_descriptor = getDescriptor().getMessageTypes().get(4); - internal_static_ocs_Auth_fieldAccessorTable = new + internal_static_ocs_Reshare_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_ocs_Auth_descriptor, - new java.lang.String[] { "Byzcoin", "Authx509Cert", }); - internal_static_ocs_AuthByzCoin_descriptor = + internal_static_ocs_Reshare_descriptor, + new java.lang.String[] { "X", "Newroster", "Auth", }); + internal_static_ocs_ReshareReply_descriptor = getDescriptor().getMessageTypes().get(5); - internal_static_ocs_AuthByzCoin_fieldAccessorTable = new + internal_static_ocs_ReshareReply_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_ocs_AuthByzCoin_descriptor, - new java.lang.String[] { "Byzcoinid", "Ttl", }); - internal_static_ocs_AuthX509Cert_descriptor = + internal_static_ocs_ReshareReply_descriptor, + new java.lang.String[] { "Sig", }); + internal_static_ocs_PolicyOCS_descriptor = getDescriptor().getMessageTypes().get(6); - internal_static_ocs_AuthX509Cert_fieldAccessorTable = new + internal_static_ocs_PolicyOCS_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_ocs_AuthX509Cert_descriptor, - new java.lang.String[] { "Ca", "Threshold", }); - internal_static_ocs_Grant_descriptor = + internal_static_ocs_PolicyOCS_descriptor, + new java.lang.String[] { "Policyreencrypt", "Policyreshare", }); + internal_static_ocs_Policy_descriptor = getDescriptor().getMessageTypes().get(7); - internal_static_ocs_Grant_fieldAccessorTable = new + internal_static_ocs_Policy_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_ocs_Grant_descriptor, - new java.lang.String[] { "Byzcoin", "X509Cert", }); - internal_static_ocs_GrantByzCoin_descriptor = + internal_static_ocs_Policy_descriptor, + new java.lang.String[] { "Byzcoin", "Authx509Cert", }); + internal_static_ocs_PolicyByzCoin_descriptor = getDescriptor().getMessageTypes().get(8); - internal_static_ocs_GrantByzCoin_fieldAccessorTable = new + internal_static_ocs_PolicyByzCoin_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_ocs_GrantByzCoin_descriptor, - new java.lang.String[] { "Write", "Read", }); - internal_static_ocs_GrantX509Cert_descriptor = + internal_static_ocs_PolicyByzCoin_descriptor, + new java.lang.String[] { "Byzcoinid", "Ttl", }); + internal_static_ocs_PolicyX509Cert_descriptor = getDescriptor().getMessageTypes().get(9); - internal_static_ocs_GrantX509Cert_fieldAccessorTable = new + internal_static_ocs_PolicyX509Cert_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_PolicyX509Cert_descriptor, + new java.lang.String[] { "Ca", "Threshold", }); + internal_static_ocs_AuthReencrypt_descriptor = + getDescriptor().getMessageTypes().get(10); + internal_static_ocs_AuthReencrypt_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_ocs_GrantX509Cert_descriptor, + internal_static_ocs_AuthReencrypt_descriptor, + new java.lang.String[] { "Byzcoin", "X509Cert", }); + internal_static_ocs_AuthReencryptByzCoin_descriptor = + getDescriptor().getMessageTypes().get(11); + internal_static_ocs_AuthReencryptByzCoin_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AuthReencryptByzCoin_descriptor, + new java.lang.String[] { "Write", "Read", }); + internal_static_ocs_AuthReencryptX509Cert_descriptor = + getDescriptor().getMessageTypes().get(12); + internal_static_ocs_AuthReencryptX509Cert_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AuthReencryptX509Cert_descriptor, new java.lang.String[] { "Secret", "Certificates", }); + internal_static_ocs_AuthReshare_descriptor = + getDescriptor().getMessageTypes().get(13); + internal_static_ocs_AuthReshare_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AuthReshare_descriptor, + new java.lang.String[] { "Byzcoin", "X509Cert", }); + internal_static_ocs_AuthReshareByzCoin_descriptor = + getDescriptor().getMessageTypes().get(14); + internal_static_ocs_AuthReshareByzCoin_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AuthReshareByzCoin_descriptor, + new java.lang.String[] { "Reshare", }); + internal_static_ocs_AuthReshareX509Cert_descriptor = + getDescriptor().getMessageTypes().get(15); + internal_static_ocs_AuthReshareX509Cert_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AuthReshareX509Cert_descriptor, + new java.lang.String[] { "Certificates", }); ch.epfl.dedis.lib.proto.OnetProto.getDescriptor(); } diff --git a/external/proto/authprox.proto b/external/proto/authprox.proto index f8f779c0c6..e92dd11171 100644 --- a/external/proto/authprox.proto +++ b/external/proto/authprox.proto @@ -18,7 +18,7 @@ message EnrollResponse { } // SignatureRequest is the request sent to this service to request that -// the Authentication Proxy check the authentication information and +// the Policy Proxy check the authentication information and // generate a signature connecting some information identifying the // holder of the AuthInfo to the message. message SignatureRequest { diff --git a/external/proto/darc.proto b/external/proto/darc.proto index 8d5a778b69..cdb0a624d2 100644 --- a/external/proto/darc.proto +++ b/external/proto/darc.proto @@ -59,7 +59,7 @@ message IdentityX509EC { } // IdentityProxy holds the info necessary to verify a claim -// from an external authentication system via an Authentication Proxy. +// from an external authentication system via an Policy Proxy. message IdentityProxy { required string data = 1; required bytes public = 2; @@ -101,7 +101,7 @@ message SignerX509EC { } // SignerProxy holds the information necessary to verify claims -// coming from external authentication systems via Authentication Proxies. +// coming from external authentication systems via Policy Proxies. message SignerProxy { required string data = 1; required bytes public = 2; diff --git a/external/proto/ocs.proto b/external/proto/ocs.proto index 3435935a0a..ab6dc1d8ca 100644 --- a/external/proto/ocs.proto +++ b/external/proto/ocs.proto @@ -12,7 +12,7 @@ option java_outer_classname = "OCS"; // CreateOCS is sent to the service to request a new OCS cothority. message CreateOCS { required onet.Roster roster = 1; - required Auth authentication = 2; + required Policy policy = 2; } // CreateOCSReply is the reply sent by the conode if the OCS has been @@ -26,78 +26,125 @@ message CreateOCSReply { } // Reencrypt is sent to the service to request a re-encryption of the -// secret given in Grant. Grant must also contain the proof that the +// secret given in AuthReencrypt. AuthReencrypt must also contain the proof that the // request is valid, as well as the ephemeral key, to which the secret // will be re-encrypted. message Reencrypt { required bytes x = 1; - required Grant grant = 2; + required AuthReencrypt auth = 2; } -// ReencryptReply is the reply if the re-encryption is successful, and +// MessageReencryptReply is the reply if the re-encryption is successful, and // it contains XHat, which is the secret re-encrypted to the ephemeral -// key given in Grant. +// key given in AuthReencrypt. message ReencryptReply { required bytes xhat = 1; } +// Reshare is called to ask OCS to change the roster. It needs a valid +// authentication before the private keys are re-generated over the new +// roster. +message Reshare { + required bytes x = 1; + required onet.Roster newroster = 2; + required AuthReshare auth = 3; +} + +// ReshareReply is returned if the resharing has been completed successfully +// and contains the collective signature on the message +// sha256( X | NewRoster ) +message ReshareReply { + required bytes sig = 1; +} + // *** // Common structures // *** -// Auth holds all possible authentication structures. When using it to call +// PolicyOCS holds the two policies necessary to define an OCS: how to +// authenticate a reencryption request, and how to authenticate a +// resharing request. +// In the current form, both policies point to the same structure. If at +// a later moment a new access control backend is added, it might be that +// the policies will differ for this new backend. +message PolicyOCS { + required Policy policyreencrypt = 1; + required Policy policyreshare = 2; +} + +// Policy holds all possible authentication structures. When using it to call // Authorise, only one of the fields must be non-nil. -message Auth { - optional AuthByzCoin byzcoin = 1; - optional AuthX509Cert authx509cert = 2; +message Policy { + optional PolicyByzCoin byzcoin = 1; + optional PolicyX509Cert authx509cert = 2; } -// AuthByzCoin holds the information necessary to authenticate a byzcoin request. +// PolicyByzCoin holds the information necessary to authenticate a byzcoin request. // In the ByzCoin model, all requests are valid as long as they are stored in the // blockchain with the given ID. // The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled. -message AuthByzCoin { +message PolicyByzCoin { required bytes byzcoinid = 1; required uint64 ttl = 2; } -// AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric +// PolicyX509Cert holds the information necessary to authenticate a HyperLedger/Fabric // request. In its simplest form, it is simply the CA that will have to sign the // certificates of the requesters. // The Threshold indicates how many clients must have signed the request before it // is accepted. -message AuthX509Cert { +message PolicyX509Cert { // Slice of ASN.1 encoded X509 certificates. repeated bytes ca = 1; required sint32 threshold = 2; } -// Grant holds one of the possible grant proofs for a reencryption request. Each -// grant proof must hold the secret to be reencrypted, the ephemeral key, as well +// AuthReencrypt holds one of the possible authentication proofs for a reencryption request. Each +// authentication proof must hold the secret to be reencrypted, the ephemeral key, as well // as the proof itself that the request is valid. For each of the authentication // schemes, this proof will be different. -message Grant { - optional GrantByzCoin byzcoin = 1; - optional GrantX509Cert x509cert = 2; +message AuthReencrypt { + optional AuthReencryptByzCoin byzcoin = 1; + optional AuthReencryptX509Cert x509cert = 2; } -// GrantByzCoin holds the proof of the write instance, holding the secret itself. +// AuthReencryptByzCoin holds the proof of the write instance, holding the secret itself. // The proof of the read instance holds the ephemeral key. Both proofs can be // verified using one of the stored ByzCoinIDs. -message GrantByzCoin { +message AuthReencryptByzCoin { // Write is the proof containing the write request. required bytes write = 1; // Read is the proof that he has been accepted to read the secret. required bytes read = 2; } -// GrantX509Cert holds the proof that at least a threshold number of clients +// AuthReencryptX509Cert holds the proof that at least a threshold number of clients // accepted the reencryption. // For each client, there must exist a certificate that can be verified by the -// CA certificate from AuthX509Cert. Additionally, each client must sign the +// CA certificate from PolicyX509Cert. Additionally, each client must sign the // following message: // sha256( Secret | Ephemeral | Time ) -message GrantX509Cert { +message AuthReencryptX509Cert { required bytes secret = 1; repeated bytes certificates = 2; } + +// AuthReshare holds the proof that at least a threshold number of clients accepted the +// request to reshare the secret key. The authentication must hold the new roster, as +// well as the proof that the new roster should be applied to a given OCS. +message AuthReshare { + optional AuthReshareByzCoin byzcoin = 1; + optional AuthReshareX509Cert x509cert = 2; +} + +// AuthReshareByzCoin holds the byzcoin-proof that contains the latest OCS-instance +// which includes the roster. The OCS-nodes will make sure that the version of the +// OCS-instance is bigger than the current version. +message AuthReshareByzCoin { + required bytes reshare = 1; +} + +// AuthReshareX509Cert holds the X509 proof that the new roster is valid. +message AuthReshareX509Cert { + repeated bytes certificates = 1; +} diff --git a/ocs/api.go b/ocs/api.go index 07bd1af141..27e05188bc 100644 --- a/ocs/api.go +++ b/ocs/api.go @@ -6,21 +6,19 @@ import ( "go.dedis.ch/onet/v3" ) -// TODO: add OCSID of type kyber.Point // TODO: think about authentication -// TODO: add CreateAndAuthorise // TODO: add REST interface type OCSID kyber.Point -// ClientV4 is a class to communicate to the calypso service. -type ClientV4 struct { +// Client is a class to communicate to the calypso service. +type Client struct { *onet.Client } // NewClientV4 creates a new client to interact with the Calypso Service. -func NewClientV4() *ClientV4 { - return &ClientV4{Client: onet.NewClient(cothority.Suite, ServiceName)} +func NewClientV4() *Client { + return &Client{Client: onet.NewClient(cothority.Suite, ServiceName)} } // CreateLTS starts a new Distributed Key Generation with the nodes in the roster and @@ -45,20 +43,38 @@ func NewClientV4() *ClientV4 { // err = schnorr.Verify(cothority.Suite, roster.ServiceAggregate(calypso.ServiceName), // msg.Sum(nil), sig) // // If err == nil, the signature is correct -func (c *ClientV4) CreateLTS(ltsRoster *onet.Roster, auth Auth) (X OCSID, sig []byte, err error) { - return +func (c *Client) CreateLTS(roster onet.Roster, auth Policy) (X OCSID, sig []byte, err error) { + var ret CreateOCSReply + err = c.SendProtobuf(roster.RandomServerIdentity(), &CreateOCS{Roster: roster, Policy: auth}, &ret) + if err != nil { + return + } + return ret.X, ret.Sig, nil } -// Reencrypt requests the re-encryption of the secret stored in the grant. -// The grant must also contain the ephemeral key to which the secret will be +// Reencrypt requests the re-encryption of the secret stored in the authentication. +// The authentication must also contain the ephemeral key to which the secret will be // reencrypted to. -// Finally the grant must contain information about how to verify that the +// Finally the authentication must contain information about how to verify that the // reencryption request is valid. // // This can be called from anywhere. // -// If the grant is valid, the reencrypted XHat is returned and err is nil. In case +// If the authentication is valid, the reencrypted XHat is returned and err is nil. In case // of error, XHat is nil, and the error will be returned. -func (c *ClientV4) Reencrypt(X kyber.Point, grant Grant) (XHat kyber.Point, err error) { - return +func (c *Client) Reencrypt(roster onet.Roster, X OCSID, auth AuthReencrypt) (XHat kyber.Point, err error) { + var ret ReencryptReply + err = c.SendProtobuf(roster.RandomServerIdentity(), &Reencrypt{X: X, Auth: auth}, &ret) + if err != nil { + return + } + return ret.XHat, nil +} + +// Reshare requests the OCS X to share the private key to a new set of nodes given in newRoster. +// The auth argument must give proof that this request is valid. +// +// If the request was successful, nil is returned, an error otherwise. +func (c *Client) Reshare(oldRoster onet.Roster, X OCSID, newRoster onet.Roster, auth AuthReshare) error { + return c.SendProtobuf(oldRoster.RandomServerIdentity(), &Reshare{X: X, NewRoster: newRoster, Auth: auth}, nil) } diff --git a/ocs/proto.go b/ocs/proto.go index 2a949ae7f3..aad0d9c29d 100644 --- a/ocs/proto.go +++ b/ocs/proto.go @@ -26,8 +26,8 @@ import ( // CreateOCS is sent to the service to request a new OCS cothority. type CreateOCS struct { - Roster onet.Roster - Authentication Auth + Roster onet.Roster + Policy Policy } // CreateOCSReply is the reply sent by the conode if the OCS has been @@ -41,78 +41,125 @@ type CreateOCSReply struct { } // Reencrypt is sent to the service to request a re-encryption of the -// secret given in Grant. Grant must also contain the proof that the +// secret given in AuthReencrypt. AuthReencrypt must also contain the proof that the // request is valid, as well as the ephemeral key, to which the secret // will be re-encrypted. type Reencrypt struct { - X OCSID - Grant Grant + X OCSID + Auth AuthReencrypt } -// ReencryptReply is the reply if the re-encryption is successful, and +// MessageReencryptReply is the reply if the re-encryption is successful, and // it contains XHat, which is the secret re-encrypted to the ephemeral -// key given in Grant. +// key given in AuthReencrypt. type ReencryptReply struct { XHat kyber.Point } +// Reshare is called to ask OCS to change the roster. It needs a valid +// authentication before the private keys are re-generated over the new +// roster. +type Reshare struct { + X OCSID + NewRoster onet.Roster + Auth AuthReshare +} + +// ReshareReply is returned if the resharing has been completed successfully +// and contains the collective signature on the message +// sha256( X | NewRoster ) +type ReshareReply struct { + Sig []byte +} + // *** // Common structures // *** -// Auth holds all possible authentication structures. When using it to call +// PolicyOCS holds the two policies necessary to define an OCS: how to +// authenticate a reencryption request, and how to authenticate a +// resharing request. +// In the current form, both policies point to the same structure. If at +// a later moment a new access control backend is added, it might be that +// the policies will differ for this new backend. +type PolicyOCS struct { + PolicyReencrypt Policy + PolicyReshare Policy +} + +// Policy holds all possible authentication structures. When using it to call // Authorise, only one of the fields must be non-nil. -type Auth struct { - ByzCoin *AuthByzCoin - AuthX509Cert *AuthX509Cert +type Policy struct { + ByzCoin *PolicyByzCoin + AuthX509Cert *PolicyX509Cert } -// AuthByzCoin holds the information necessary to authenticate a byzcoin request. +// PolicyByzCoin holds the information necessary to authenticate a byzcoin request. // In the ByzCoin model, all requests are valid as long as they are stored in the // blockchain with the given ID. // The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled. -type AuthByzCoin struct { +type PolicyByzCoin struct { ByzCoinID skipchain.SkipBlockID TTL time.Time } -// AuthX509Cert holds the information necessary to authenticate a HyperLedger/Fabric +// PolicyX509Cert holds the information necessary to authenticate a HyperLedger/Fabric // request. In its simplest form, it is simply the CA that will have to sign the // certificates of the requesters. // The Threshold indicates how many clients must have signed the request before it // is accepted. -type AuthX509Cert struct { +type PolicyX509Cert struct { // Slice of ASN.1 encoded X509 certificates. CA [][]byte Threshold int } -// Grant holds one of the possible grant proofs for a reencryption request. Each -// grant proof must hold the secret to be reencrypted, the ephemeral key, as well +// AuthReencrypt holds one of the possible authentication proofs for a reencryption request. Each +// authentication proof must hold the secret to be reencrypted, the ephemeral key, as well // as the proof itself that the request is valid. For each of the authentication // schemes, this proof will be different. -type Grant struct { - ByzCoin *GrantByzCoin - X509Cert *GrantX509Cert +type AuthReencrypt struct { + ByzCoin *AuthReencryptByzCoin + X509Cert *AuthReencryptX509Cert } -// GrantByzCoin holds the proof of the write instance, holding the secret itself. +// AuthReencryptByzCoin holds the proof of the write instance, holding the secret itself. // The proof of the read instance holds the ephemeral key. Both proofs can be // verified using one of the stored ByzCoinIDs. -type GrantByzCoin struct { +type AuthReencryptByzCoin struct { // Write is the proof containing the write request. Write byzcoin.Proof // Read is the proof that he has been accepted to read the secret. Read byzcoin.Proof } -// GrantX509Cert holds the proof that at least a threshold number of clients +// AuthReencryptX509Cert holds the proof that at least a threshold number of clients // accepted the reencryption. // For each client, there must exist a certificate that can be verified by the -// CA certificate from AuthX509Cert. Additionally, each client must sign the +// CA certificate from PolicyX509Cert. Additionally, each client must sign the // following message: // sha256( Secret | Ephemeral | Time ) -type GrantX509Cert struct { +type AuthReencryptX509Cert struct { Secret kyber.Point Certificates [][]byte } + +// AuthReshare holds the proof that at least a threshold number of clients accepted the +// request to reshare the secret key. The authentication must hold the new roster, as +// well as the proof that the new roster should be applied to a given OCS. +type AuthReshare struct { + ByzCoin *AuthReshareByzCoin + X509Cert *AuthReshareX509Cert +} + +// AuthReshareByzCoin holds the byzcoin-proof that contains the latest OCS-instance +// which includes the roster. The OCS-nodes will make sure that the version of the +// OCS-instance is bigger than the current version. +type AuthReshareByzCoin struct { + Reshare byzcoin.Proof +} + +// AuthReshareX509Cert holds the X509 proof that the new roster is valid. +type AuthReshareX509Cert struct { + Certificates [][]byte +} diff --git a/ocs/protocol.go b/ocs/protocol.go index c3f0780f4e..d494b98115 100644 --- a/ocs/protocol.go +++ b/ocs/protocol.go @@ -112,7 +112,7 @@ func (o *OCS) reencrypt(r structReencrypt) error { } if o.Verify != nil { - if !o.Verify(&r.Reencrypt) { + if !o.Verify(&r.MessageReencrypt) { log.Lvl2(o.ServerIdentity(), "refused to reencrypt") return o.SendToParent(&ReencryptReply{}) } @@ -138,7 +138,7 @@ func (o *OCS) reencrypt(r structReencrypt) error { // reencryptReply is the root-node waiting for all replies and generating // the reencryption key. func (o *OCS) reencryptReply(rr structReencryptReply) error { - if rr.ReencryptReply.Ui == nil { + if rr.MessageReencryptReply.Ui == nil { log.Lvl2("Node", rr.ServerIdentity, "refused to reply") o.Failures++ if o.Failures > len(o.Roster().List)-o.Threshold { @@ -147,7 +147,7 @@ func (o *OCS) reencryptReply(rr structReencryptReply) error { } return nil } - o.replies = append(o.replies, rr.ReencryptReply) + o.replies = append(o.replies, rr.MessageReencryptReply) // minus one to exclude the root if len(o.replies) >= int(o.Threshold-1) { diff --git a/ocs/protocol_struct.go b/ocs/protocol_struct.go index 5e3e0dd713..fffa8e1627 100644 --- a/ocs/protocol_struct.go +++ b/ocs/protocol_struct.go @@ -15,17 +15,17 @@ import ( const NameOCS = "OCS" func init() { - network.RegisterMessages(&Reencrypt{}, &ReencryptReply{}) + network.RegisterMessages(&MessageReencrypt{}, &MessageReencryptReply{}) } // VerifyRequest is a callback-function that can be set by a service. // Whenever a reencryption request is received, this function will be // called and its return-value used to determine whether or not to // allow reencryption. -type VerifyRequest func(rc *Reencrypt) bool +type VerifyRequest func(rc *MessageReencrypt) bool // Reencrypt asks for a re-encryption share from a node -type Reencrypt struct { +type MessageReencrypt struct { // U is the point from the write-request U kyber.Point // Xc is the public key of the reader @@ -37,11 +37,11 @@ type Reencrypt struct { type structReencrypt struct { *onet.TreeNode - Reencrypt + MessageReencrypt } -// ReencryptReply returns the share to re-encrypt from one node -type ReencryptReply struct { +// MessageReencryptReply returns the share to re-encrypt from one node +type MessageReencryptReply struct { Ui *share.PubShare Ei kyber.Scalar Fi kyber.Scalar @@ -49,5 +49,5 @@ type ReencryptReply struct { type structReencryptReply struct { *onet.TreeNode - ReencryptReply + MessageReencryptReply } diff --git a/skipchain/msgs.go b/skipchain/msgs.go index 5b0a1362d7..bcc9481762 100644 --- a/skipchain/msgs.go +++ b/skipchain/msgs.go @@ -293,8 +293,8 @@ type EmptyReply struct{} // SettingAuthentication sets the authentication bit that enables restriction // of the skipchains that are accepted. It needs to be signed by one of the -// clients. The signature is on []byte{0} if Authentication is false and on -// []byte{1} if the Authentication is true. +// clients. The signature is on []byte{0} if Policy is false and on +// []byte{1} if the Policy is true. // TODO: perhaps we need to protect this against replay-attacks by adding a // monotonically increasing nonce that is also stored on the conode. type SettingAuthentication struct { diff --git a/skipchain/skipchain.go b/skipchain/skipchain.go index eaca84c3d0..be3030453d 100644 --- a/skipchain/skipchain.go +++ b/skipchain/skipchain.go @@ -650,7 +650,7 @@ func (s *Service) CreateLinkPrivate(link *CreateLinkPrivate) (*EmptyReply, error } // Unlink removes a public key from the list of linked nodes. -// Authentication to unlink is done by a signature on the +// Policy to unlink is done by a signature on the // following message: // "unlink:" + byte representation of the public key to be // removed From c7c3858210047135e93f6e450e371dd13d60b9cd Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Wed, 10 Apr 2019 13:04:18 +0200 Subject: [PATCH 04/21] first pass on api, struct, service, and protocol --- calypso/api.go | 6 +- calypso/api_test.go | 6 +- calypso/proto.go | 4 +- calypso/service.go | 4 +- go.mod | 1 + ocs/api.go | 12 +- ocs/db.go | 31 +-- ocs/proto.go | 38 ++-- ocs/protocol.go | 6 +- ocs/service.go | 513 +++++++++++++++++++------------------------- ocs/service_test.go | 1 + ocs/struct.go | 39 ++++ 12 files changed, 312 insertions(+), 349 deletions(-) create mode 100644 ocs/service_test.go create mode 100644 ocs/struct.go diff --git a/calypso/api.go b/calypso/api.go index 9cad053612..f2b230accd 100644 --- a/calypso/api.go +++ b/calypso/api.go @@ -40,7 +40,7 @@ func NewClient(byzcoin *byzcoin.Client) *Client { cothority.Suite, ServiceName)} } -// CreateLTS creates a random LTSID that can be used to reference the LTS group +// CreateOCS creates a random LTSID that can be used to reference the LTS group // created. It first sends a transaction to ByzCoin to spawn a LTS instance, // then it asks the Calypso cothority to start the DKG. func (c *Client) CreateLTS(ltsRoster *onet.Roster, darcID darc.ID, signers []darc.Signer, counters []uint64) (reply *CreateLTSReply, err error) { @@ -103,7 +103,7 @@ func (c *Client) Authorise(who *network.ServerIdentity, what skipchain.SkipBlock return nil } -// DecryptKey takes as input Read- and Write- Proofs. It verifies that +// Reencrypt takes as input Read- and Write- Proofs. It verifies that // the read/write requests match and then re-encrypts the secret // given the public key information of the reader. func (c *Client) DecryptKey(dkr *DecryptKey) (reply *DecryptKeyReply, err error) { @@ -261,7 +261,7 @@ func (c *Client) SpawnDarc(signer darc.Signer, signerCtr uint64, } // RecoverKey is used to recover the secret key once it has been -// re-encrypted to a given public key by the DecryptKey method +// re-encrypted to a given public key by the Reencrypt method // in the Calypso service. The resulting secret key can be used // with a symmetric decryption algorithm to decrypt the data // stored in the Data field of the WriteInstance. diff --git a/calypso/api_test.go b/calypso/api_test.go index 106e7b2d17..494b78b528 100644 --- a/calypso/api_test.go +++ b/calypso/api_test.go @@ -12,7 +12,7 @@ import ( "go.dedis.ch/onet/v3" ) -// Tests the client function CreateLTS +// Tests the client function CreateOCS func TestClient_CreateLTS(t *testing.T) { l := onet.NewTCPTest(cothority.Suite) _, roster, _ := l.GenTree(3, true) @@ -37,7 +37,7 @@ func TestClient_CreateLTS(t *testing.T) { require.NoError(t, err) } - // Invoke CreateLTS + // Invoke CreateOCS ltsReply, err := calypsoClient.CreateLTS(roster, d.GetBaseID(), []darc.Signer{signer}, []uint64{1}) require.Nil(t, err) require.NotNil(t, ltsReply.ByzCoinID) @@ -47,7 +47,7 @@ func TestClient_CreateLTS(t *testing.T) { // TODO(jallen): Write TestClient_Reshare (and add api.go part too, I guess) -// Tests the client api's AddRead, AddWrite, DecryptKey +// Tests the client api's AddRead, AddWrite, Reencrypt func TestClient_Calypso(t *testing.T) { l := onet.NewTCPTest(cothority.Suite) _, roster, _ := l.GenTree(3, true) diff --git a/calypso/proto.go b/calypso/proto.go index fa30d8030e..5a69a21116 100644 --- a/calypso/proto.go +++ b/calypso/proto.go @@ -69,7 +69,7 @@ type Authorise struct { type AuthoriseReply struct { } -// CreateLTS is used to start a DKG and store the private keys in each node. +// CreateOCS is used to start a DKG and store the private keys in each node. // Prior to using this request, the Calypso roster must be recorded on the // ByzCoin blockchain in the instance specified by InstanceID. type CreateLTS struct { @@ -97,7 +97,7 @@ type ReshareLTS struct { type ReshareLTSReply struct { } -// DecryptKey is sent by a reader after he successfully stored a 'Read' request +// Reencrypt is sent by a reader after he successfully stored a 'Read' request // in byzcoin Client. type DecryptKey struct { // Read is the proof that he has been accepted to read the secret. diff --git a/calypso/service.go b/calypso/service.go index 3b7963f1ae..9849131e78 100644 --- a/calypso/service.go +++ b/calypso/service.go @@ -140,7 +140,7 @@ func (s *Service) Authorise(req *Authorise) (*AuthoriseReply, error) { return &AuthoriseReply{}, nil } -// CreateLTS takes as input a roster with a list of all nodes that should +// CreateOCS takes as input a roster with a list of all nodes that should // participate in the DKG. Every node will store its private key and wait for // decryption requests. The LTSID should be the InstanceID. func (s *Service) CreateLTS(req *CreateLTS) (reply *CreateLTSReply, err error) { @@ -340,7 +340,7 @@ func (s *Service) getLtsRoster(proof *byzcoin.Proof) (*onet.Roster, byzcoin.Inst return &info.Roster, byzcoin.NewInstanceID(instanceID), nil } -// DecryptKey takes as an input a Read- and a Write-proof. Proofs contain +// Reencrypt takes as an input a Read- and a Write-proof. Proofs contain // everything necessary to verify that a given instance is correct and // stored in ByzCoin. // Using the Read and the Write-instance, this method verifies that the diff --git a/go.mod b/go.mod index e63f065896..d41254137b 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( go.dedis.ch/onet/v3 v3.0.2 go.dedis.ch/protobuf v1.0.6 go.etcd.io/bbolt v1.3.0 + golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b golang.org/x/oauth2 v0.0.0-20190115181402-5dab4167f31c golang.org/x/sys v0.0.0-20190124100055-b90733256f2e golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 // indirect diff --git a/ocs/api.go b/ocs/api.go index 27e05188bc..6daa0da59a 100644 --- a/ocs/api.go +++ b/ocs/api.go @@ -21,7 +21,7 @@ func NewClientV4() *Client { return &Client{Client: onet.NewClient(cothority.Suite, ServiceName)} } -// CreateLTS starts a new Distributed Key Generation with the nodes in the roster and +// CreateOCS starts a new Distributed Key Generation with the nodes in the roster and // returns the collective public key X. This X is also used later to identify the // LTS instance, as there can be more than one LTS group on a node. // @@ -43,9 +43,13 @@ func NewClientV4() *Client { // err = schnorr.Verify(cothority.Suite, roster.ServiceAggregate(calypso.ServiceName), // msg.Sum(nil), sig) // // If err == nil, the signature is correct -func (c *Client) CreateLTS(roster onet.Roster, auth Policy) (X OCSID, sig []byte, err error) { +func (c *Client) CreateOCS(roster onet.Roster, policyReencrypt, policyReshare Policy) (X OCSID, sig []byte, err error) { var ret CreateOCSReply - err = c.SendProtobuf(roster.RandomServerIdentity(), &CreateOCS{Roster: roster, Policy: auth}, &ret) + err = c.SendProtobuf(roster.RandomServerIdentity(), &CreateOCS{ + Roster: roster, + PolicyReencrypt: policyReencrypt, + PolicyReshare: policyReshare, + }, &ret) if err != nil { return } @@ -68,7 +72,7 @@ func (c *Client) Reencrypt(roster onet.Roster, X OCSID, auth AuthReencrypt) (XHa if err != nil { return } - return ret.XHat, nil + return ret.X, nil } // Reshare requests the OCS X to share the private key to a new set of nodes given in newRoster. diff --git a/ocs/db.go b/ocs/db.go index a6f39eda1f..5e4b9d7131 100644 --- a/ocs/db.go +++ b/ocs/db.go @@ -4,7 +4,6 @@ import ( "errors" "sync" - "go.dedis.ch/cothority/v3/byzcoin" dkgprotocol "go.dedis.ch/cothority/v3/dkg/pedersen" dkg "go.dedis.ch/kyber/v3/share/dkg/pedersen" "go.dedis.ch/onet/v3" @@ -19,16 +18,18 @@ var storageKey = []byte("storage") // storage is used to save all elements of the DKG. type storage struct { - AuthorisedByzCoinIDs map[string]bool - - Shared map[byzcoin.InstanceID]*dkgprotocol.SharedSecret - Polys map[byzcoin.InstanceID]*pubPoly - Rosters map[byzcoin.InstanceID]*onet.Roster - DKS map[byzcoin.InstanceID]*dkg.DistKeyShare + Element map[string]*storageElement sync.Mutex } +type storageElement struct { + Shared dkgprotocol.SharedSecret + Polys pubPoly + Roster onet.Roster + DKS dkg.DistKeyShare +} + // saves all data. func (s *Service) save() error { s.storage.Lock() @@ -52,20 +53,8 @@ func (s *Service) tryLoad() error { // Make sure we don't have any unallocated maps. defer func() { - if len(s.storage.Polys) == 0 { - s.storage.Polys = make(map[byzcoin.InstanceID]*pubPoly) - } - if len(s.storage.Shared) == 0 { - s.storage.Shared = make(map[byzcoin.InstanceID]*dkgprotocol.SharedSecret) - } - if len(s.storage.Rosters) == 0 { - s.storage.Rosters = make(map[byzcoin.InstanceID]*onet.Roster) - } - if len(s.storage.DKS) == 0 { - s.storage.DKS = make(map[byzcoin.InstanceID]*dkg.DistKeyShare) - } - if len(s.storage.AuthorisedByzCoinIDs) == 0 { - s.storage.AuthorisedByzCoinIDs = make(map[string]bool) + if len(s.storage.Element) == 0 { + s.storage.Element = make(map[string]*storageElement) } }() diff --git a/ocs/proto.go b/ocs/proto.go index aad0d9c29d..13b7dedded 100644 --- a/ocs/proto.go +++ b/ocs/proto.go @@ -3,6 +3,8 @@ package ocs import ( "time" + "go.dedis.ch/cothority/v3/darc" + "go.dedis.ch/cothority/v3/byzcoin" "go.dedis.ch/cothority/v3/skipchain" "go.dedis.ch/kyber/v3" @@ -25,9 +27,16 @@ import ( // *** // CreateOCS is sent to the service to request a new OCS cothority. +// It holds the two policies necessary to define an OCS: how to +// authenticate a reencryption request, and how to authenticate a +// resharing request. +// In the current form, both policies point to the same structure. If at +// a later moment a new access control backend is added, it might be that +// the policies will differ for this new backend. type CreateOCS struct { - Roster onet.Roster - Policy Policy + Roster onet.Roster + PolicyReencrypt Policy + PolicyReshare Policy } // CreateOCSReply is the reply sent by the conode if the OCS has been @@ -53,12 +62,16 @@ type Reencrypt struct { // it contains XHat, which is the secret re-encrypted to the ephemeral // key given in AuthReencrypt. type ReencryptReply struct { - XHat kyber.Point + X kyber.Point + XhatEnc kyber.Point + C kyber.Point } // Reshare is called to ask OCS to change the roster. It needs a valid -// authentication before the private keys are re-generated over the new +// authentication before the private keys are re-distributed over the new // roster. +// TODO: should NewRoster be always present in AuthReshare? It will be present +// TODO: at least in AuthReshareByzCoin, but might not in other AuthReshares type Reshare struct { X OCSID NewRoster onet.Roster @@ -76,17 +89,6 @@ type ReshareReply struct { // Common structures // *** -// PolicyOCS holds the two policies necessary to define an OCS: how to -// authenticate a reencryption request, and how to authenticate a -// resharing request. -// In the current form, both policies point to the same structure. If at -// a later moment a new access control backend is added, it might be that -// the policies will differ for this new backend. -type PolicyOCS struct { - PolicyReencrypt Policy - PolicyReshare Policy -} - // Policy holds all possible authentication structures. When using it to call // Authorise, only one of the fields must be non-nil. type Policy struct { @@ -131,6 +133,12 @@ type AuthReencryptByzCoin struct { Write byzcoin.Proof // Read is the proof that he has been accepted to read the secret. Read byzcoin.Proof + // Ephemeral can be non-nil to point to a key to which the data needs to be + // re-encrypted to, but then Signature also needs to be non-nil. + Ephemeral kyber.Point + // If Ephemeral si non-nil, it must be signed by the darc responsible for the + // Read instance to make sure it's a valid reencryption-request. + Signature *darc.Signature } // AuthReencryptX509Cert holds the proof that at least a threshold number of clients diff --git a/ocs/protocol.go b/ocs/protocol.go index d494b98115..53e7b7256c 100644 --- a/ocs/protocol.go +++ b/ocs/protocol.go @@ -44,7 +44,7 @@ type OCS struct { Reencrypted chan bool Uis []*share.PubShare // re-encrypted shares // private fields - replies []ReencryptReply + replies []MessageReencryptReply timeout *time.Timer doneOnce sync.Once } @@ -75,7 +75,7 @@ func (o *OCS) Start() error { o.finish(false) return errors.New("please initialize U first") } - rc := &Reencrypt{ + rc := &MessageReencrypt{ U: o.U, Xc: o.Xc, } @@ -128,7 +128,7 @@ func (o *OCS) reencrypt(r structReencrypt) error { hiHat.MarshalTo(hash) ei := cothority.Suite.Scalar().SetBytes(hash.Sum(nil)) - return o.SendToParent(&ReencryptReply{ + return o.SendToParent(&MessageReencryptReply{ Ui: ui, Ei: ei, Fi: cothority.Suite.Scalar().Add(si, cothority.Suite.Scalar().Mul(ei, o.Shared.V)), diff --git a/ocs/service.go b/ocs/service.go index 05ae31988f..0fe04b805b 100644 --- a/ocs/service.go +++ b/ocs/service.go @@ -13,11 +13,7 @@ import ( "time" "go.dedis.ch/cothority/v3" - "go.dedis.ch/cothority/v3/byzcoin" - "go.dedis.ch/cothority/v3/darc" dkgprotocol "go.dedis.ch/cothority/v3/dkg/pedersen" - "go.dedis.ch/cothority/v3/ocs/protocol" - "go.dedis.ch/cothority/v3/skipchain" "go.dedis.ch/kyber/v3" "go.dedis.ch/kyber/v3/share" dkg "go.dedis.ch/kyber/v3/share/dkg/pedersen" @@ -37,7 +33,7 @@ const ServiceName = "OCS" // dkgTimeout is how long the system waits for the DKG to finish const propagationTimeout = 20 * time.Second -const calypsoReshareProto = "calypso_reshare_proto" +const calypsoReshareProto = "ocs_reshare_proto" var disableLoopbackCheck = false @@ -47,7 +43,7 @@ func init() { log.ErrFatal(err) OCSServiceID, err = onet.RegisterNewService(ServiceName, newService) log.ErrFatal(err) - network.RegisterMessages(&storage{}, &vData{}) + network.RegisterMessages(&storage{}, &storageElement{}) // The loopback check makes Java testing not work, because Java client commands // come from outside of the docker container. The Java testing Docker @@ -71,20 +67,11 @@ type pubPoly struct { Commits []kyber.Point } -// vData is sent to all nodes when re-encryption takes place. If Ephemeral -// is non-nil, Signature needs to hold a valid signature from the reader -// in the Proof. -type vData struct { - Proof byzcoin.Proof - Ephemeral kyber.Point - Signature *darc.Signature -} - // ProcessClientRequest implements onet.Service. We override the version // we normally get from embeddeding onet.ServiceProcessor in order to // hook it and get a look at the http.Request. func (s *Service) ProcessClientRequest(req *http.Request, path string, buf []byte) ([]byte, *onet.StreamingTunnel, error) { - if !disableLoopbackCheck && path == "Authorise" { + if !disableLoopbackCheck && path == "CreateOCS" { h, _, err := net.SplitHostPort(req.RemoteAddr) if err != nil { return nil, nil, err @@ -99,43 +86,17 @@ func (s *Service) ProcessClientRequest(req *http.Request, path string, buf []byt return s.ServiceProcessor.ProcessClientRequest(req, path, buf) } -// Authorise adds a ByzCoinID to the list of authorized IDs. It should -// be called by the administrator at the beginning, before any other API calls -// are made. A ByzCoinID that is not authorised will not be allowed to call the -// other APIs. -func (s *Service) Authorise(req *Authorise) (*AuthoriseReply, error) { - s.storage.Lock() - defer s.storage.Unlock() - if len(req.ByzCoinID) == 0 { - return nil, errors.New("empty ByzCoin ID") - } - key := string(req.ByzCoinID) - if _, ok := s.storage.AuthorisedByzCoinIDs[key]; ok { - return nil, errors.New("ByzCoinID already authorised") - } - s.storage.AuthorisedByzCoinIDs[key] = true - return &AuthoriseReply{}, nil -} - -// CreateLTS takes as input a roster with a list of all nodes that should +// CreateOCS takes as input a roster with a list of all nodes that should // participate in the DKG. Every node will store its private key and wait for -// decryption requests. The OCSID should be the InstanceID. -func (s *Service) CreateLTS(req *CreateLTS) (reply *CreateLTSReply, err error) { - if err := s.verifyProof(&req.Proof, nil); err != nil { - return nil, err - } - - roster, instID, err := s.getLtsRoster(&req.Proof) - if err != nil { - return nil, err +// decryption requests. +func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { + if err = req.verify(); err != nil { + return } // NOTE: the roster stored in ByzCoin must have myself. - tree := roster.GenerateNaryTreeWithRoot(len(roster.List), s.ServerIdentity()) - cfg := newLtsConfig{ - req.Proof, - } - cfgBuf, err := protobuf.Encode(&cfg) + tree := req.Roster.GenerateNaryTreeWithRoot(len(req.Roster.List), s.ServerIdentity()) + cfgBuf, err := protobuf.Encode(&req) if err != nil { return nil, err } @@ -152,227 +113,77 @@ func (s *Service) CreateLTS(req *CreateLTS) (reply *CreateLTSReply, err error) { return nil, err } - log.Lvl3("Started DKG-protocol - waiting for done", len(roster.List)) + log.Lvl3("Started DKG-protocol - waiting for done", len(req.Roster.List)) select { case <-setupDKG.Finished: shared, dks, err := setupDKG.SharedSecret() if err != nil { return nil, err } - reply = &CreateLTSReply{ - ByzCoinID: req.Proof.Latest.SkipChainID(), - InstanceID: instID, - X: shared.X, + reply = &CreateOCSReply{ + X: shared.X, + // TODO: calculate signature + Sig: []byte{}, } - s.storage.Lock() - s.storage.Shared[instID] = shared - s.storage.Polys[instID] = &pubPoly{s.Suite().Point().Base(), dks.Commits} - s.storage.Rosters[instID] = roster - s.storage.Replies[instID] = reply - s.storage.DKS[instID] = dks - s.storage.Unlock() - s.save() - log.Lvlf2("%v Created LTS with ID: %v, pk %v", s.ServerIdentity(), instID, reply.X) - case <-time.After(propagationTimeout): - return nil, errors.New("new-dkg didn't finish in time") - } - return -} - -// ReshareLTS starts a request to reshare the LTS. The new roster which holds -// the new secret shares must exist in the proof specified by the request. -// All hosts must be online in this step. -func (s *Service) ReshareLTS(req *ReshareLTS) (*ReshareLTSReply, error) { - // Verify the request - roster, id, err := s.getLtsRoster(&req.Proof) - if err != nil { - return nil, err - } - if err := s.verifyProof(&req.Proof, roster); err != nil { - return nil, err - } - - // Initialise the protocol - setupDKG, err := func() (*dkgprotocol.Setup, error) { - s.storage.Lock() - defer s.storage.Unlock() - - // Check that we know the shared secret, otherwise don't do re-sharing - if s.storage.Shared[id] == nil || s.storage.DKS[id] == nil { - return nil, errors.New("cannot start resharing without an LTS") - } - - // NOTE: the roster stored in ByzCoin must have myself. - tree := roster.GenerateNaryTreeWithRoot(len(roster.List), s.ServerIdentity()) - cfg := reshareLtsConfig{ - Proof: req.Proof, - // We pass the public coefficients out with the protocol, - // because new nodes will need it for their dkg.Config.PublicCoeffs. - Commits: s.storage.DKS[id].Commits, - OldNodes: s.storage.Rosters[id].Publics(), - } - cfgBuf, err := protobuf.Encode(&cfg) - if err != nil { - return nil, err - } - pi, err := s.CreateProtocol(calypsoReshareProto, tree) - if err != nil { - return nil, err - } - setupDKG := pi.(*dkgprotocol.Setup) - setupDKG.Wait = true - setupDKG.KeyPair = s.getKeyPair() - setupDKG.SetConfig(&onet.GenericConfig{Data: cfgBuf}) - - // Because we are the node starting the resharing protocol, by - // definition, we are inside the old group. (Checked first thing - // in this function.) So we have only Share, not PublicCoeffs. - n := len(roster.List) - c := &dkg.Config{ - Suite: cothority.Suite, - Longterm: setupDKG.KeyPair.Private, - OldNodes: s.storage.Rosters[id].Publics(), - NewNodes: roster.Publics(), - Share: s.storage.DKS[id], - Threshold: n - (n-1)/3, - } - setupDKG.NewDKG = func() (*dkg.DistKeyGenerator, error) { - d, err := dkg.NewDistKeyHandler(c) - return d, err - } - return setupDKG, nil - }() - if err != nil { - return nil, err - } - if err := setupDKG.Start(); err != nil { - return nil, err - } - log.Lvl3(s.ServerIdentity(), "Started resharing DKG-protocol - waiting for done") - - var pk kyber.Point - select { - case <-setupDKG.Finished: - shared, dks, err := setupDKG.SharedSecret() + oid, err := shared.X.MarshalBinary() if err != nil { return nil, err } - pk = shared.X s.storage.Lock() - // Check the secret shares are different - if shared.V.Equal(s.storage.Shared[id].V) { - s.storage.Unlock() - return nil, errors.New("the reshared secret is the same") + s.storage.Element[string(oid)] = &storageElement{ + Shared: *shared, + Polys: pubPoly{s.Suite().Point().Base(), dks.Commits}, + Roster: req.Roster, + DKS: *dks, } - // Check the public key remains the same - if !shared.X.Equal(s.storage.Shared[id].X) { - s.storage.Unlock() - return nil, errors.New("the reshared public point is different") - } - s.storage.Shared[id] = shared - s.storage.Polys[id] = &pubPoly{s.Suite().Point().Base(), dks.Commits} - s.storage.Rosters[id] = roster - s.storage.DKS[id] = dks s.storage.Unlock() s.save() - if s.afterReshare != nil { - s.afterReshare() - } + log.Lvlf2("%v Created LTS with ID: %v, pk %v", s.ServerIdentity(), string(oid), reply.X) case <-time.After(propagationTimeout): - return nil, errors.New("resharing-dkg didn't finish in time") - } - - log.Lvl2(s.ServerIdentity(), "resharing protocol finished") - log.Lvlf2("%v Reshared LTS with ID: %v, pk %v", s.ServerIdentity(), id, pk) - return &ReshareLTSReply{}, nil -} - -func (s *Service) verifyProof(proof *byzcoin.Proof, roster *onet.Roster) error { - scID := proof.Latest.SkipChainID() - s.storage.Lock() - defer s.storage.Unlock() - if _, ok := s.storage.AuthorisedByzCoinIDs[string(scID)]; !ok { - return errors.New("this ByzCoin ID is not authorised") - } - - // We used to check that the roster ID did not change here, but with - // resharing, it is expected that the roster can change. - // TODO: Confirm with Kelong that this is correct to remove; that this - // does not open us up to abuse/attack. - - return proof.Verify(scID) -} - -func (s *Service) getLtsRoster(proof *byzcoin.Proof) (*onet.Roster, byzcoin.InstanceID, error) { - instanceID, buf, _, _, err := proof.KeyValue() - if err != nil { - return nil, byzcoin.InstanceID{}, err - } - - var info LtsInstanceInfo - err = protobuf.DecodeWithConstructors(buf, &info, network.DefaultConstructors(cothority.Suite)) - if err != nil { - return nil, byzcoin.InstanceID{}, err + return nil, errors.New("new-dkg didn't finish in time") } - return &info.Roster, byzcoin.NewInstanceID(instanceID), nil + return } -// DecryptKey takes as an input a Read- and a Write-proof. Proofs contain +// Reencrypt takes as an input a Read- and a Write-proof. Proofs contain // everything necessary to verify that a given instance is correct and // stored in ByzCoin. // Using the Read and the Write-instance, this method verifies that the // requests match and then re-encrypts the secret to the public key given // in the Read-instance. -func (s *Service) DecryptKey(dkr *DecryptKey) (reply *DecryptKeyReply, err error) { - reply = &DecryptKeyReply{} +func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { + reply = &ReencryptReply{} log.Lvl2(s.ServerIdentity(), "Re-encrypt the key to the public key of the reader") - var read Read - if err := dkr.Read.VerifyAndDecode(cothority.Suite, ContractReadID, &read); err != nil { - return nil, errors.New("didn't get a read instance: " + err.Error()) + if err = dkr.Auth.verify(dkr.X); err != nil { + return } - var write Write - if err := dkr.Write.VerifyAndDecode(cothority.Suite, ContractWriteID, &write); err != nil { - return nil, errors.New("didn't get a write instance: " + err.Error()) - } - if !read.Write.Equal(byzcoin.NewInstanceID(dkr.Write.InclusionProof.Key())) { - return nil, errors.New("read doesn't point to passed write") - } s.storage.Lock() - id := write.LTSID - roster := s.storage.Rosters[id] - if roster == nil { - s.storage.Unlock() - return nil, fmt.Errorf("don't know the OCSID '%v' stored in write", id) - } - scID := make([]byte, 32) - copy(scID, s.storage.Replies[id].ByzCoinID) - s.storage.Unlock() - if err = dkr.Read.Verify(scID); err != nil { - return nil, errors.New("read proof cannot be verified to come from scID: " + err.Error()) + idBuf, err := dkr.X.MarshalBinary() + if err != nil { + return } - if err = dkr.Write.Verify(scID); err != nil { - return nil, errors.New("write proof cannot be verified to come from scID: " + err.Error()) + id := string(idBuf) + se, found := s.storage.Element[id] + if !found { + s.storage.Unlock() + return nil, fmt.Errorf("don't know the OCSID '%v'", id) } - // Start ocs-protocol to re-encrypt the file's symmetric key under the - // reader's public key. - nodes := len(roster.List) + // Start the ocs-protocol to re-encrypt the data under the public key of the reader. + nodes := len(se.Roster.List) threshold := nodes - (nodes-1)/3 - tree := roster.GenerateNaryTreeWithRoot(nodes, s.ServerIdentity()) - pi, err := s.CreateProtocol(protocol.NameOCS, tree) + tree := se.Roster.GenerateNaryTreeWithRoot(nodes, s.ServerIdentity()) + pi, err := s.CreateProtocol(NameOCS, tree) if err != nil { return nil, err } - ocsProto := pi.(*protocol.OCS) - ocsProto.U = write.U - verificationData := &vData{ - Proof: dkr.Read, - } - ocsProto.Xc = read.Xc + ocsProto := pi.(*OCS) + ocsProto.U = dkr.Auth.X509Cert.Secret + ocsProto.Xc = dkr.Auth.Xc() log.Lvlf2("%v Public key is: %s", s.ServerIdentity(), ocsProto.Xc) - ocsProto.VerificationData, err = protobuf.Encode(verificationData) + ocsProto.VerificationData, err = protobuf.Encode(dkr.Auth) if err != nil { return nil, errors.New("couldn't marshal verification data: " + err.Error()) } @@ -380,9 +191,14 @@ func (s *Service) DecryptKey(dkr *DecryptKey) (reply *DecryptKeyReply, err error // Make sure everything used from the s.Storage structure is copied, so // there will be no races. s.storage.Lock() - ocsProto.Shared = s.storage.Shared[id] - pp := s.storage.Polys[id] - reply.X = s.storage.Shared[id].X.Clone() + es, found := s.storage.Element[id] + if !found { + s.storage.Unlock() + return nil, errors.New("didn't find shared structure") + } + ocsProto.Shared = &es.Shared + pp := es.Polys + reply.X = es.Shared.X.Clone() var commits []kyber.Point for _, c := range pp.Commits { commits = append(commits, c.Clone()) @@ -391,7 +207,7 @@ func (s *Service) DecryptKey(dkr *DecryptKey) (reply *DecryptKeyReply, err error s.storage.Unlock() log.Lvl3("Starting reencryption protocol") - ocsProto.SetConfig(&onet.GenericConfig{Data: id.Slice()}) + ocsProto.SetConfig(&onet.GenericConfig{Data: []byte(id)}) err = ocsProto.Start() if err != nil { return nil, err @@ -405,25 +221,118 @@ func (s *Service) DecryptKey(dkr *DecryptKey) (reply *DecryptKeyReply, err error if err != nil { return nil, err } - reply.C = write.C + reply.C = dkr.Auth.C() log.Lvl3("Successfully reencrypted the key") return } -// GetLTSReply returns the CreateLTSReply message of a previous LTS. -func (s *Service) GetLTSReply(req *GetLTSReply) (*CreateLTSReply, error) { - log.Lvlf2("Getting LTS Reply for ID: %v", req.LTSID) - s.storage.Lock() - defer s.storage.Unlock() - reply, ok := s.storage.Replies[req.LTSID] - if !ok { - return nil, fmt.Errorf("didn't find this LTS: %v", req.LTSID) - } - return &CreateLTSReply{ - ByzCoinID: append([]byte{}, reply.ByzCoinID...), - InstanceID: reply.InstanceID, - X: reply.X.Clone(), - }, nil +// ReshareLTS starts a request to reshare the LTS. The new roster which holds +// the new secret shares must exist in the proof specified by the request. +// All hosts must be online in this step. +func (s *Service) ReshareLTS(req *Reshare) (*ReshareReply, error) { + return nil, errors.New("not yet implemented") + //// Verify the request + //roster, id, err := s.getLtsRoster(&req.Proof) + //if err != nil { + // return nil, err + //} + //if err := s.verifyProof(&req.Proof, roster); err != nil { + // return nil, err + //} + // + //// Initialise the protocol + //setupDKG, err := func() (*dkgprotocol.Setup, error) { + // s.storage.Lock() + // defer s.storage.Unlock() + // + // // Check that we know the shared secret, otherwise don't do re-sharing + // if s.storage.Shared[id] == nil || s.storage.DKS[id] == nil { + // return nil, errors.New("cannot start resharing without an LTS") + // } + // + // // NOTE: the roster stored in ByzCoin must have myself. + // tree := roster.GenerateNaryTreeWithRoot(len(roster.List), s.ServerIdentity()) + // cfg := reshareLtsConfig{ + // Proof: req.Proof, + // // We pass the public coefficients out with the protocol, + // // because new nodes will need it for their dkg.Config.PublicCoeffs. + // Commits: s.storage.DKS[id].Commits, + // OldNodes: s.storage.Rosters[id].Publics(), + // } + // cfgBuf, err := protobuf.Encode(&cfg) + // if err != nil { + // return nil, err + // } + // pi, err := s.CreateProtocol(calypsoReshareProto, tree) + // if err != nil { + // return nil, err + // } + // setupDKG := pi.(*dkgprotocol.Setup) + // setupDKG.Wait = true + // setupDKG.KeyPair = s.getKeyPair() + // setupDKG.SetConfig(&onet.GenericConfig{Data: cfgBuf}) + // + // // Because we are the node starting the resharing protocol, by + // // definition, we are inside the old group. (Checked first thing + // // in this function.) So we have only Share, not PublicCoeffs. + // n := len(roster.List) + // c := &dkg.Config{ + // Suite: cothority.Suite, + // Longterm: setupDKG.KeyPair.Private, + // OldNodes: s.storage.Rosters[id].Publics(), + // NewNodes: roster.Publics(), + // Share: s.storage.DKS[id], + // Threshold: n - (n-1)/3, + // } + // setupDKG.NewDKG = func() (*dkg.DistKeyGenerator, error) { + // d, err := dkg.NewDistKeyHandler(c) + // return d, err + // } + // return setupDKG, nil + //}() + //if err != nil { + // return nil, err + //} + //if err := setupDKG.Start(); err != nil { + // return nil, err + //} + //log.Lvl3(s.ServerIdentity(), "Started resharing DKG-protocol - waiting for done") + // + //var pk kyber.Point + //select { + //case <-setupDKG.Finished: + // shared, dks, err := setupDKG.SharedSecret() + // if err != nil { + // return nil, err + // } + // pk = shared.X + // s.storage.Lock() + // // Check the secret shares are different + // if shared.V.Equal(s.storage.Shared[id].V) { + // s.storage.Unlock() + // return nil, errors.New("the reshared secret is the same") + // } + // // Check the public key remains the same + // if !shared.X.Equal(s.storage.Shared[id].X) { + // s.storage.Unlock() + // return nil, errors.New("the reshared public point is different") + // } + // s.storage.Shared[id] = shared + // s.storage.Polys[id] = &pubPoly{s.Suite().Point().Base(), dks.Commits} + // s.storage.Rosters[id] = roster + // s.storage.DKS[id] = dks + // s.storage.Unlock() + // s.save() + // if s.afterReshare != nil { + // s.afterReshare() + // } + //case <-time.After(propagationTimeout): + // return nil, errors.New("resharing-dkg didn't finish in time") + //} + // + //log.Lvl2(s.ServerIdentity(), "resharing protocol finished") + //log.Lvlf2("%v Reshared LTS with ID: %v, pk %v", s.ServerIdentity(), id, pk) + //return &ReshareLTSReply{}, nil } func (s *Service) getKeyPair() *key.Pair { @@ -440,18 +349,13 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi log.Lvl3(s.ServerIdentity(), tn.ProtocolName(), conf) switch tn.ProtocolName() { case dkgprotocol.Name: - var cfg newLtsConfig + var cfg CreateOCS if err := protobuf.DecodeWithConstructors(conf.Data, &cfg, network.DefaultConstructors(cothority.Suite)); err != nil { return nil, err } - if err := s.verifyProof(&cfg.Proof, tn.Roster()); err != nil { - return nil, err - } - key, _, _, _, err := cfg.KeyValue() - if err != nil { + if err := cfg.verify(); err != nil { return nil, err } - instID := byzcoin.NewInstanceID(key) pi, err := dkgprotocol.NewSetup(tn) if err != nil { @@ -460,40 +364,40 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi setupDKG := pi.(*dkgprotocol.Setup) setupDKG.KeyPair = s.getKeyPair() - go func(bcID skipchain.SkipBlockID, id byzcoin.InstanceID) { + go func() { <-setupDKG.Finished shared, dks, err := setupDKG.SharedSecret() if err != nil { log.Error(err) return } - reply := &CreateLTSReply{ - ByzCoinID: bcID, - InstanceID: instID, - X: shared.X, + idBuf, err := shared.X.MarshalBinary() + if err != nil { + log.Error(err) + return } + id := string(idBuf) log.Lvlf3("%v got shared %v on inst %v", s.ServerIdentity(), shared, id) s.storage.Lock() - s.storage.Shared[id] = shared - s.storage.DKS[id] = dks - s.storage.Replies[id] = reply - s.storage.Rosters[id] = tn.Roster() + s.storage.Element[string(id)] = &storageElement{ + Shared: *shared, + Roster: *tn.Roster(), + DKS: *dks, + } s.storage.Unlock() s.save() - }(cfg.Latest.SkipChainID(), instID) + }() return pi, nil case calypsoReshareProto: // Decode and verify config - var cfg reshareLtsConfig + var cfg Reshare if err := protobuf.DecodeWithConstructors(conf.Data, &cfg, network.DefaultConstructors(cothority.Suite)); err != nil { return nil, err } - if err := s.verifyProof(&cfg.Proof, tn.Roster()); err != nil { + if err := cfg.verify(); err != nil { return nil, err } - _, id, err := s.getLtsRoster(&cfg.Proof) - // Set up the protocol pi, err := dkgprotocol.NewSetup(tn) if err != nil { @@ -503,23 +407,35 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi setupDKG.KeyPair = s.getKeyPair() s.storage.Lock() + idBuf, err := cfg.X.MarshalBinary() + if err != nil { + return nil, err + } + id := string(idBuf) + es, found := s.storage.Element[id] + if !found { + // TODO: we might not have this yet - so probably we need to put the old roster in cfg, too. + return nil, errors.New("this OCSID is not known here") + } + oldNodes := es.Roster.Publics() n := len(tn.Roster().List) c := &dkg.Config{ Suite: cothority.Suite, Longterm: setupDKG.KeyPair.Private, NewNodes: tn.Roster().Publics(), - OldNodes: cfg.OldNodes, + OldNodes: oldNodes, Threshold: n - (n-1)/3, } - s.storage.Unlock() // Set Share and PublicCoeffs according to if we are an old node or a new one. - inOld := pointInList(setupDKG.KeyPair.Public, cfg.OldNodes) + inOld := pointInList(setupDKG.KeyPair.Public, oldNodes) if inOld { - c.Share = s.storage.DKS[id] + c.Share = &es.DKS } else { - c.PublicCoeffs = cfg.Commits + // TODO: add commits here + //c.PublicCoeffs = cfg.Commits } + s.storage.Unlock() setupDKG.NewDKG = func() (*dkg.DistKeyGenerator, error) { d, err := dkg.NewDistKeyHandler(c) @@ -531,7 +447,7 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi } // Wait for DKG in reshare mode to end - go func(id byzcoin.InstanceID) { + go func() { <-setupDKG.Finished shared, dks, err := setupDKG.SharedSecret() if err != nil { @@ -540,46 +456,51 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi } s.storage.Lock() + es, found := s.storage.Element[id] // If we had an old share, check the new share before saving it. - if s.storage.Shared[id] != nil { + if found { // Check the secret shares are different - if shared.V.Equal(s.storage.Shared[id].V) { + if shared.V.Equal(es.Shared.V) { s.storage.Unlock() log.Error("the reshared secret is the same") return } // Check the public key remains the same - if !shared.X.Equal(s.storage.Shared[id].X) { + if !shared.X.Equal(es.Shared.X) { s.storage.Unlock() log.Error("the reshared public point is different") return } + } else { + es = &storageElement{} } - s.storage.Shared[id] = shared - s.storage.DKS[id] = dks + // TODO: what happens with Polys here? + es.Roster = cfg.NewRoster + es.Shared = *shared + es.DKS = *dks + s.storage.Unlock() s.save() if s.afterReshare != nil { s.afterReshare() } - }(id) + }() return setupDKG, nil - case protocol.NameOCS: - id := byzcoin.NewInstanceID(conf.Data) + case NameOCS: + id := string(conf.Data) s.storage.Lock() - shared, ok := s.storage.Shared[id] - shared = shared.Clone() + es, ok := s.storage.Element[id] s.storage.Unlock() if !ok { return nil, fmt.Errorf("didn't find OCSID %v", id) } - pi, err := protocol.NewOCS(tn) + pi, err := NewOCS(tn) if err != nil { return nil, err } - ocs := pi.(*protocol.OCS) - ocs.Shared = shared + ocs := pi.(*OCS) + ocs.Shared = es.Shared.Clone() ocs.Verify = s.verifyReencryption return ocs, nil } @@ -596,7 +517,8 @@ func pointInList(p1 kyber.Point, l []kyber.Point) bool { } // verifyReencryption checks that the read and the write instances match. -func (s *Service) verifyReencryption(rc *protocol.Reencrypt) bool { +func (s *Service) verifyReencryption(rc *MessageReencrypt) bool { + // TODO: check the correct authentication return false } @@ -607,8 +529,7 @@ func newService(c *onet.Context) (onet.Service, error) { s := &Service{ ServiceProcessor: onet.NewServiceProcessor(c), } - if err := s.RegisterHandlers(s.CreateLTS, s.ReshareLTS, s.DecryptKey, - s.GetLTSReply, s.Authorise); err != nil { + if err := s.RegisterHandlers(s.CreateOCS, s.ReshareLTS, s.Reencrypt); err != nil { return nil, errors.New("couldn't register messages") } if err := s.tryLoad(); err != nil { diff --git a/ocs/service_test.go b/ocs/service_test.go new file mode 100644 index 0000000000..571eb2cbbb --- /dev/null +++ b/ocs/service_test.go @@ -0,0 +1 @@ +package ocs diff --git a/ocs/struct.go b/ocs/struct.go new file mode 100644 index 0000000000..ce628918e2 --- /dev/null +++ b/ocs/struct.go @@ -0,0 +1,39 @@ +package ocs + +import ( + "errors" + + "go.dedis.ch/kyber/v3" + + "go.dedis.ch/onet/v3" +) + +func (ocs CreateOCS) verify() error { + if err := ocs.PolicyReencrypt.verify(ocs.Roster); err != nil { + return err + } + if err := ocs.PolicyReshare.verify(ocs.Roster); err != nil { + return err + } + return nil +} + +func (re Reshare) verify() error { + return errors.New("not yet implemented") +} + +func (p Policy) verify(r onet.Roster) error { + return errors.New("not yet implemented") +} + +func (ar AuthReencrypt) verify(X OCSID) error { + return errors.New("not yet implemented") +} + +func (ar AuthReencrypt) Xc() kyber.Point { + return nil +} + +func (ar AuthReencrypt) C() kyber.Point { + return nil +} From 03748df38266bddd50a85b74c0e6db5630774b32 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Wed, 10 Apr 2019 18:13:47 +0200 Subject: [PATCH 05/21] cleaned up the Encode / Decode --- calypso/proto.go | 5 +- go.mod | 11 ++-- go.sum | 10 +++ ocs/OCS.md | 17 +++++ ocs/proto.go | 13 ++-- ocs/protocol.go | 14 ++-- ocs/protocol_test.go | 65 +++++++++--------- ocs/service.go | 152 +++++++++++++++++++++++++++---------------- ocs/service_test.go | 101 ++++++++++++++++++++++++++++ ocs/struct.go | 71 ++++++++++++++++++-- ocs/verify.go | 2 + 11 files changed, 346 insertions(+), 115 deletions(-) diff --git a/calypso/proto.go b/calypso/proto.go index 5a69a21116..ff87a09a4e 100644 --- a/calypso/proto.go +++ b/calypso/proto.go @@ -39,8 +39,9 @@ type Write struct { // f is the proof - written in uppercase here so it is an exported // field, but in the OCS-paper it's lowercase. F kyber.Scalar - // C is the ElGamal parts for the symmetric key material (might also - // contain an IV) + // C is the ElGamal part for the symmetric key material, at maximum length + // of ed25519.Point.EmbedLen * 8 = 240 bits. An eventual IV must be published + // in ExtraData, as it is not necessary to be encrypted. C kyber.Point // ExtraData is clear text and application-specific ExtraData []byte `protobuf:"opt"` diff --git a/go.mod b/go.mod index d41254137b..50196848d7 100644 --- a/go.mod +++ b/go.mod @@ -4,22 +4,23 @@ require ( github.com/BurntSushi/toml v0.3.1 github.com/bford/golang-x-crypto v0.0.0-20160518072526-27db609c9d03 github.com/coreos/go-oidc v2.0.0+incompatible - github.com/davecgh/go-spew v1.1.1 // indirect github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect github.com/prataprc/goparsec v0.0.0-20180806094145-2600a2a4a410 github.com/qantik/qrgo v0.0.0-20160917134849-0c6b902c59f6 github.com/satori/go.uuid v1.2.0 github.com/stretchr/testify v1.3.0 - go.dedis.ch/kyber/v3 v3.0.0 + go.dedis.ch/kyber/v3 v3.0.2 go.dedis.ch/onet/v3 v3.0.2 go.dedis.ch/protobuf v1.0.6 - go.etcd.io/bbolt v1.3.0 - golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b + go.etcd.io/bbolt v1.3.2 + golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576 golang.org/x/oauth2 v0.0.0-20190115181402-5dab4167f31c - golang.org/x/sys v0.0.0-20190124100055-b90733256f2e + golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 // indirect gopkg.in/satori/go.uuid.v1 v1.2.0 gopkg.in/square/go-jose.v2 v2.2.2 // indirect gopkg.in/urfave/cli.v1 v1.20.0 ) + +replace go.dedis.ch/onet/v3 => ../onet diff --git a/go.sum b/go.sum index f49c71aa56..6335d924ce 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,7 @@ github.com/qantik/qrgo v0.0.0-20160917134849-0c6b902c59f6/go.mod h1:if1RdEJ8j9Pb github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= @@ -51,6 +52,8 @@ go.dedis.ch/kyber/v3 v3.0.0-pre2 h1:ezviD36AEOytXJn91tsvQeR+rEzo3UOh75P/PzSisRo= go.dedis.ch/kyber/v3 v3.0.0-pre2/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= go.dedis.ch/kyber/v3 v3.0.0 h1:XuefPFGJKPyfPBD6kXctbLb4smT9Il5HmUn303JRr08= go.dedis.ch/kyber/v3 v3.0.0/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= +go.dedis.ch/kyber/v3 v3.0.2 h1:dhYLJksmOau7TYf1JS0iTpW6Bus+mtqxJBbM0Q/E9HU= +go.dedis.ch/kyber/v3 v3.0.2/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= go.dedis.ch/onet/v3 v3.0.2 h1:+jBLnoQBHMDJ1lVgkcbmkKNWqXma8n9R/5/7VZ1wZls= go.dedis.ch/onet/v3 v3.0.2/go.mod h1:xqmP2+NvxeNzgmNj/4hf56EZm3KT0Qksz98miZw5G3A= go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo= @@ -58,8 +61,12 @@ go.dedis.ch/protobuf v1.0.6 h1:E61p2XjYbYrTf3WeXE8M8Ui5WA3hX/NgbHHi5D0FLxI= go.dedis.ch/protobuf v1.0.6/go.mod h1:YHYXW6dQ9p2iJ3f+2fxKnOpjGx0MvL4cwpg1RVNXaV8= go.etcd.io/bbolt v1.3.0 h1:oY10fI923Q5pVCVt1GBTZMn8LHo5M+RCInFpeMnV4QI= go.etcd.io/bbolt v1.3.0/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b h1:Elez2XeF2p9uyVj0yEUDqQ56NFcDtcBNkYP7yv8YbUE= golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576 h1:aUX/1G2gFSs4AsJJg2cL3HuoRhCSCz733FE5GUSuaT4= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY= @@ -70,6 +77,9 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FY golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190124100055-b90733256f2e h1:3GIlrlVLfkoipSReOMNAgApI0ajnalyLa/EZHHca/XI= golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc h1:4gbWbmmPFp4ySWICouJl6emP0MyS31yy9SrTlAGFT+g= +golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To= diff --git a/ocs/OCS.md b/ocs/OCS.md index afbc9b1769..9f4db7a37f 100644 --- a/ocs/OCS.md +++ b/ocs/OCS.md @@ -32,3 +32,20 @@ shared key from the DKG can be re-encrypted under another public key without the data being in the clear at any given moment. This is used in the onchain-secrets skipchain when a reader wants to recover the symmetric key. + +# Variables used + +When going through the code, the variables follow the CALYPSO paper +in the Appendix B under **Secret reconstruction at the trusted server** +as far as possible. + +Here is a short recap of the different variable-names used in the +re-encryption: + +- X: the aggregate public key of the OCS (LTS), also used as the +ID of the OCS +- C: the ElGamal part of the data, with maximal key-length of 240 bits for +Ed25519 +- U: the encrypted random value for the ElGamal encryption +- Xc: the public key of the reader under which U will be re-encrypted +- XHatEnc: the re-encrypted random value for the ElGamal encryption \ No newline at end of file diff --git a/ocs/proto.go b/ocs/proto.go index 13b7dedded..8d6936590b 100644 --- a/ocs/proto.go +++ b/ocs/proto.go @@ -92,8 +92,8 @@ type ReshareReply struct { // Policy holds all possible authentication structures. When using it to call // Authorise, only one of the fields must be non-nil. type Policy struct { - ByzCoin *PolicyByzCoin - AuthX509Cert *PolicyX509Cert + ByzCoin *PolicyByzCoin + X509Cert *PolicyX509Cert } // PolicyByzCoin holds the information necessary to authenticate a byzcoin request. @@ -105,7 +105,7 @@ type PolicyByzCoin struct { TTL time.Time } -// PolicyX509Cert holds the information necessary to authenticate a HyperLedger/Fabric +// X509Cert holds the information necessary to authenticate a HyperLedger/Fabric // request. In its simplest form, it is simply the CA that will have to sign the // certificates of the requesters. // The Threshold indicates how many clients must have signed the request before it @@ -121,8 +121,9 @@ type PolicyX509Cert struct { // as the proof itself that the request is valid. For each of the authentication // schemes, this proof will be different. type AuthReencrypt struct { - ByzCoin *AuthReencryptByzCoin - X509Cert *AuthReencryptX509Cert + Ephemeral kyber.Point + ByzCoin *AuthReencryptByzCoin + X509Cert *AuthReencryptX509Cert } // AuthReencryptByzCoin holds the proof of the write instance, holding the secret itself. @@ -144,7 +145,7 @@ type AuthReencryptByzCoin struct { // AuthReencryptX509Cert holds the proof that at least a threshold number of clients // accepted the reencryption. // For each client, there must exist a certificate that can be verified by the -// CA certificate from PolicyX509Cert. Additionally, each client must sign the +// CA certificate from X509Cert. Additionally, each client must sign the // following message: // sha256( Secret | Ephemeral | Time ) type AuthReencryptX509Cert struct { diff --git a/ocs/protocol.go b/ocs/protocol.go index 53e7b7256c..4775083b80 100644 --- a/ocs/protocol.go +++ b/ocs/protocol.go @@ -67,6 +67,10 @@ func NewOCS(n *onet.TreeNodeInstance) (onet.ProtocolInstance, error) { // Start asks all children to reply with a shared reencryption func (o *OCS) Start() error { log.Lvl3("Starting Protocol") + o.timeout = time.AfterFunc(1*time.Minute, func() { + log.Lvl1("OCS protocol timeout") + o.finish(false) + }) if o.Shared == nil { o.finish(false) return errors.New("please initialize Shared first") @@ -75,6 +79,10 @@ func (o *OCS) Start() error { o.finish(false) return errors.New("please initialize U first") } + if o.Xc == nil { + o.finish(false) + return errors.New("please initialize Xc first") + } rc := &MessageReencrypt{ U: o.U, Xc: o.Xc, @@ -88,10 +96,6 @@ func (o *OCS) Start() error { return errors.New("refused to reencrypt") } } - o.timeout = time.AfterFunc(1*time.Minute, func() { - log.Lvl1("OCS protocol timeout") - o.finish(false) - }) errs := o.Broadcast(rc) if len(errs) > (len(o.Roster().List)-1)/3 { log.Errorf("Some nodes failed with error(s) %v", errs) @@ -114,7 +118,7 @@ func (o *OCS) reencrypt(r structReencrypt) error { if o.Verify != nil { if !o.Verify(&r.MessageReencrypt) { log.Lvl2(o.ServerIdentity(), "refused to reencrypt") - return o.SendToParent(&ReencryptReply{}) + return o.SendToParent(&MessageReencryptReply{}) } } diff --git a/ocs/protocol_test.go b/ocs/protocol_test.go index a54721828a..03c8722aaa 100644 --- a/ocs/protocol_test.go +++ b/ocs/protocol_test.go @@ -31,7 +31,7 @@ const testServiceName = "ServiceOCS" func init() { var err error - testServiceID, err = onet.RegisterNewService(testServiceName, newService) + testServiceID, err = onet.RegisterNewService(testServiceName, newTestService) log.ErrFatal(err) } @@ -89,8 +89,9 @@ func TestOnchain(t *testing.T) { if err != nil { t.Fatal(err) } - U, Cs := EncodeKey(suite, X, k[:]) - // U and Cs is shared with everybody + U, C, err := EncodeKey(suite, X, k[:]) + require.NoError(t, err) + // U and C is shared with everybody // Reader's keypair xc := key.NewKeyPair(cothority.Suite) @@ -113,7 +114,7 @@ func TestOnchain(t *testing.T) { log.ErrFatal(err) // Decrypt XhatEnc - keyHat, err := DecodeKey(suite, X, Cs, XhatEnc, xc.Private) + keyHat, err := DecodeKey(suite, X, C, XhatEnc, xc.Private) log.ErrFatal(err) // Extract the message - keyHat is the recovered key @@ -271,10 +272,11 @@ func ocs(t *testing.T, nbrNodes, threshold, keylen, fail int, refuse bool) { require.Nil(t, err) X := dks.Public() - // 2 - writer - Encrypt a symmetric key and publish U, Cs + // 2 - writer - Encrypt a symmetric key and publish U, C k := make([]byte, keylen) random.Bytes(k, random.New()) - U, Cs := EncodeKey(tSuite, X, k) + U, C, err := EncodeKey(tSuite, X, k) + require.NoError(t, err) // 3 - reader - Makes a request to U by giving his public key Xc // xc is the client's private/publick key pair @@ -321,7 +323,7 @@ func ocs(t *testing.T, nbrNodes, threshold, keylen, fail int, refuse bool) { require.Nil(t, err, "Reencryption failed") // 6 - reader - gets the resulting symmetric key, encrypted under Xc - keyHat, err := DecodeKey(suite, X, Cs, XhatEnc, xc.Private) + keyHat, err := DecodeKey(suite, X, C, XhatEnc, xc.Private) require.Nil(t, err) require.Equal(t, k, keyHat) @@ -357,7 +359,7 @@ func (s *testService) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericC } ocs := pi.(*OCS) ocs.Shared = s.Shared - ocs.Verify = func(rc *Reencrypt) bool { + ocs.Verify = func(rc *MessageReencrypt) bool { return rc.VerificationData != nil } return ocs, nil @@ -379,23 +381,21 @@ func (s *testService) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericC // // Output: // - U - the schnorr commit -// - Cs - encrypted key-slices -func EncodeKey(suite suites.Suite, X kyber.Point, key []byte) (U kyber.Point, Cs []kyber.Point) { +// - C - encrypted key +func EncodeKey(suite suites.Suite, X kyber.Point, key []byte) (U kyber.Point, C kyber.Point, err error) { + if len(key) > suite.Point().EmbedLen() { + return nil, nil, errors.New("got more data than can fit into one point") + } r := suite.Scalar().Pick(suite.RandomStream()) - C := suite.Point().Mul(r, X) + C = suite.Point().Mul(r, X) log.Lvl3("C:", C.String()) U = suite.Point().Mul(r, nil) log.Lvl3("U is:", U.String()) - for len(key) > 0 { - var kp kyber.Point - kp = suite.Point().Embed(key, suite.RandomStream()) - log.Lvl3("Keypoint:", kp.String()) - log.Lvl3("X:", X.String()) - Cs = append(Cs, suite.Point().Add(C, kp)) - log.Lvl3("Cs:", C.String()) - key = key[min(len(key), kp.EmbedLen()):] - } + kp := suite.Point().Embed(key, suite.RandomStream()) + log.Lvl3("Keypoint:", kp.String()) + log.Lvl3("X:", X.String()) + C.Add(C, kp) return } @@ -406,14 +406,14 @@ func EncodeKey(suite suites.Suite, X kyber.Point, key []byte) (U kyber.Point, Cs // Input: // - suite - the cryptographic suite to use // - X - the aggregate public key of the DKG -// - Cs - the encrypted key-slices +// - C - the encrypted key // - XhatEnc - the re-encrypted schnorr-commit // - xc - the private key of the reader // // Output: // - key - the re-assembled key // - err - an eventual error when trying to recover the data from the points -func DecodeKey(suite kyber.Group, X kyber.Point, Cs []kyber.Point, XhatEnc kyber.Point, +func DecodeKey(suite kyber.Group, X kyber.Point, C kyber.Point, XhatEnc kyber.Point, xc kyber.Scalar) (key []byte, err error) { log.Lvl3("xc:", xc) xcInv := suite.Scalar().Neg(xc) @@ -429,23 +429,20 @@ func DecodeKey(suite kyber.Group, X kyber.Point, Cs []kyber.Point, XhatEnc kyber XhatInv := suite.Point().Neg(Xhat) log.Lvl3("XhatInv:", XhatInv) - // Decrypt Cs to keyPointHat - for _, C := range Cs { - log.Lvl3("C:", C) - keyPointHat := suite.Point().Add(C, XhatInv) - log.Lvl3("keyPointHat:", keyPointHat) - keyPart, err := keyPointHat.Data() - log.Lvl3("keyPart:", keyPart) - if err != nil { - return nil, err - } - key = append(key, keyPart...) + // Decrypt C to keyPointHat + log.Lvl3("C:", C) + keyPointHat := suite.Point().Add(C, XhatInv) + log.Lvl3("keyPointHat:", keyPointHat) + key, err = keyPointHat.Data() + if err != nil { + return nil, erret(err) } + log.Lvl3("key:", key) return } // starts a new service. No function needed. -func newService(c *onet.Context) (onet.Service, error) { +func newTestService(c *onet.Context) (onet.Service, error) { s := &testService{ ServiceProcessor: onet.NewServiceProcessor(c), } diff --git a/ocs/service.go b/ocs/service.go index 0fe04b805b..f6a3494bae 100644 --- a/ocs/service.go +++ b/ocs/service.go @@ -91,18 +91,18 @@ func (s *Service) ProcessClientRequest(req *http.Request, path string, buf []byt // decryption requests. func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { if err = req.verify(); err != nil { - return + return nil, erret(err) } // NOTE: the roster stored in ByzCoin must have myself. tree := req.Roster.GenerateNaryTreeWithRoot(len(req.Roster.List), s.ServerIdentity()) - cfgBuf, err := protobuf.Encode(&req) + cfgBuf, err := protobuf.Encode(req) if err != nil { - return nil, err + return nil, erret(err) } pi, err := s.CreateProtocol(dkgprotocol.Name, tree) if err != nil { - return nil, err + return nil, erret(err) } setupDKG := pi.(*dkgprotocol.Setup) setupDKG.Wait = true @@ -110,7 +110,7 @@ func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { setupDKG.KeyPair = s.getKeyPair() if err := pi.Start(); err != nil { - return nil, err + return nil, erret(err) } log.Lvl3("Started DKG-protocol - waiting for done", len(req.Roster.List)) @@ -118,7 +118,7 @@ func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { case <-setupDKG.Finished: shared, dks, err := setupDKG.SharedSecret() if err != nil { - return nil, err + return nil, erret(err) } reply = &CreateOCSReply{ X: shared.X, @@ -127,7 +127,7 @@ func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { } oid, err := shared.X.MarshalBinary() if err != nil { - return nil, err + return nil, erret(err) } s.storage.Lock() s.storage.Element[string(oid)] = &storageElement{ @@ -138,7 +138,7 @@ func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { } s.storage.Unlock() s.save() - log.Lvlf2("%v Created LTS with ID: %v, pk %v", s.ServerIdentity(), string(oid), reply.X) + log.Lvlf2("%v Created LTS with ID (=^pubKey): %x", s.ServerIdentity(), oid) case <-time.After(propagationTimeout): return nil, errors.New("new-dkg didn't finish in time") } @@ -159,69 +159,85 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { return } - s.storage.Lock() - idBuf, err := dkr.X.MarshalBinary() - if err != nil { - return - } - id := string(idBuf) - se, found := s.storage.Element[id] - if !found { - s.storage.Unlock() - return nil, fmt.Errorf("don't know the OCSID '%v'", id) - } + var threshold int + var nodes int + var id string + var ocsProto *OCS + err = func() error { + s.storage.Lock() + defer s.storage.Unlock() + idBuf, err := dkr.X.MarshalBinary() + if err != nil { + return erret(err) + } + id = string(idBuf) + se, found := s.storage.Element[id] + if !found { + return fmt.Errorf("don't know the OCSID '%v'", id) + } + + // Start the ocs-protocol to re-encrypt the data under the public key of the reader. + nodes = len(se.Roster.List) + threshold = nodes - (nodes-1)/3 + tree := se.Roster.GenerateNaryTreeWithRoot(nodes, s.ServerIdentity()) + pi, err := s.CreateProtocol(NameOCS, tree) + if err != nil { + return erret(err) + } + ocsProto = pi.(*OCS) + ocsProto.U = dkr.Auth.X509Cert.Secret + ocsProto.Xc, err = dkr.Auth.Xc() + if err != nil { + return erret(err) + } + log.Lvlf2("%v Public key is: %s", s.ServerIdentity(), ocsProto.Xc) + ocsProto.VerificationData, err = protobuf.Encode(&dkr.Auth) + if err != nil { + return errors.New("couldn't marshal verification data: " + err.Error()) + } - // Start the ocs-protocol to re-encrypt the data under the public key of the reader. - nodes := len(se.Roster.List) - threshold := nodes - (nodes-1)/3 - tree := se.Roster.GenerateNaryTreeWithRoot(nodes, s.ServerIdentity()) - pi, err := s.CreateProtocol(NameOCS, tree) + // Make sure everything used from the s.Storage structure is copied, so + // there will be no races. + es, found := s.storage.Element[id] + if !found { + return errors.New("didn't find shared structure") + } + ocsProto.Shared = &es.Shared + pp := es.Polys + reply.X = es.Shared.X.Clone() + var commits []kyber.Point + for _, c := range pp.Commits { + commits = append(commits, c.Clone()) + } + ocsProto.Poly = share.NewPubPoly(s.Suite(), pp.B.Clone(), commits) + return nil + }() if err != nil { return nil, err } - ocsProto := pi.(*OCS) - ocsProto.U = dkr.Auth.X509Cert.Secret - ocsProto.Xc = dkr.Auth.Xc() - log.Lvlf2("%v Public key is: %s", s.ServerIdentity(), ocsProto.Xc) - ocsProto.VerificationData, err = protobuf.Encode(dkr.Auth) - if err != nil { - return nil, errors.New("couldn't marshal verification data: " + err.Error()) - } - // Make sure everything used from the s.Storage structure is copied, so - // there will be no races. - s.storage.Lock() - es, found := s.storage.Element[id] - if !found { - s.storage.Unlock() - return nil, errors.New("didn't find shared structure") - } - ocsProto.Shared = &es.Shared - pp := es.Polys - reply.X = es.Shared.X.Clone() - var commits []kyber.Point - for _, c := range pp.Commits { - commits = append(commits, c.Clone()) + log.LLvl3("Starting reencryption protocol") + err = ocsProto.SetConfig(&onet.GenericConfig{Data: []byte(id)}) + if err != nil { + return nil, erret(err) } - ocsProto.Poly = share.NewPubPoly(s.Suite(), pp.B.Clone(), commits) - s.storage.Unlock() - - log.Lvl3("Starting reencryption protocol") - ocsProto.SetConfig(&onet.GenericConfig{Data: []byte(id)}) err = ocsProto.Start() if err != nil { - return nil, err + return nil, erret(err) } if !<-ocsProto.Reencrypted { return nil, errors.New("reencryption got refused") } - log.Lvl3("Reencryption protocol is done.") + log.LLvl3("Reencryption protocol is done.") reply.XhatEnc, err = share.RecoverCommit(cothority.Suite, ocsProto.Uis, threshold, nodes) if err != nil { - return nil, err + return nil, erret(err) + } + reply.C, err = dkr.Auth.C() + if err != nil { + return nil, erret(err) } - reply.C = dkr.Auth.C() log.Lvl3("Successfully reencrypted the key") return } @@ -346,7 +362,7 @@ func (s *Service) getKeyPair() *key.Pair { // NewProtocol intercepts the DKG and OCS protocols to retrieve the values func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfig) (onet.ProtocolInstance, error) { - log.Lvl3(s.ServerIdentity(), tn.ProtocolName(), conf) + log.LLvl3(s.ServerIdentity(), tn.ProtocolName(), len(conf.Data)) switch tn.ProtocolName() { case dkgprotocol.Name: var cfg CreateOCS @@ -519,7 +535,29 @@ func pointInList(p1 kyber.Point, l []kyber.Point) bool { // verifyReencryption checks that the read and the write instances match. func (s *Service) verifyReencryption(rc *MessageReencrypt) bool { // TODO: check the correct authentication - return false + err := func() error { + if rc.VerificationData == nil { + return errors.New("need verification data") + } + var arc AuthReencrypt + err := protobuf.DecodeWithConstructors(*rc.VerificationData, &arc, network.DefaultConstructors(cothority.Suite)) + if err != nil { + return erret(err) + } + Xc, err := arc.Xc() + if err != nil { + return erret(err) + } + if !Xc.Equal(rc.Xc) { + return errors.New("Xcs don't match up") + } + return nil + }() + if err != nil { + log.Error(err) + return false + } + return true } // newService receives the context that holds information about the node it's diff --git a/ocs/service_test.go b/ocs/service_test.go index 571eb2cbbb..e61c07bb80 100644 --- a/ocs/service_test.go +++ b/ocs/service_test.go @@ -1 +1,102 @@ package ocs + +import ( + "testing" + + "go.dedis.ch/kyber/v3/util/key" + + "go.dedis.ch/onet/v3/log" + + "go.dedis.ch/cothority/v3" + + "github.com/stretchr/testify/require" + + "go.dedis.ch/onet/v3" +) + +func TestMain(m *testing.M) { + log.MainTest(m, 2) +} + +// Test creation of a new OCS, both with a valid and with an invalid certificate. +func TestService_CreateOCS(t *testing.T) { + local := onet.NewLocalTest(tSuite) + defer local.CloseAll() + nbrNodes := 5 + servers, roster, _ := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) + + // Test setting up a new OCS with a valid X509 + s1 := servers[0].Service(ServiceName).(*Service) + + px := Policy{ + X509Cert: &PolicyX509Cert{}, + } + co := &CreateOCS{ + Roster: *roster, + PolicyReencrypt: px, + PolicyReshare: px, + } + cor, err := s1.CreateOCS(co) + require.NoError(t, err) + require.NotNil(t, cor) + require.NotNil(t, cor.X) + require.NoError(t, co.CheckOCSSignature(cor.Sig, cor.X)) + + // Do the same with an invalid X509 + px.X509Cert.CA = nil + co = &CreateOCS{ + Roster: *roster, + PolicyReencrypt: px, + PolicyReshare: px, + } + cor, err = s1.CreateOCS(co) + require.Error(t, err) + + // TODO: test setting up a new OCS with ByzCoin +} + +// Encrypt some data and then re-encrypt it to another public key. +func TestService_Reencrypt(t *testing.T) { + local := onet.NewLocalTest(tSuite) + defer local.CloseAll() + nbrNodes := 5 + servers, roster, _ := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) + + // Test setting up a new OCS with a valid X509 + s1 := servers[0].Service(ServiceName).(*Service) + + px := Policy{ + X509Cert: &PolicyX509Cert{}, + } + co := &CreateOCS{ + Roster: *roster, + PolicyReencrypt: px, + PolicyReshare: px, + } + cor, err := s1.CreateOCS(co) + require.NoError(t, err) + require.NoError(t, co.CheckOCSSignature(cor.Sig, cor.X)) + + secret := []byte("ocs for all") + U, C, err := EncodeKey(cothority.Suite, cor.X, secret) + require.NoError(t, err) + log.Print(U, C) + + kp := key.NewKeyPair(cothority.Suite) + rr, err := s1.Reencrypt(&Reencrypt{ + X: cor.X, + Auth: AuthReencrypt{ + Ephemeral: kp.Public, + X509Cert: &AuthReencryptX509Cert{ + Secret: U, + Certificates: nil, + }, + }, + }) + require.NoError(t, err) + + log.Print(C, rr.C) + secretRec, err := DecodeKey(cothority.Suite, cor.X, C, rr.XhatEnc, kp.Private) + require.NoError(t, err) + require.Equal(t, secret, secretRec) +} diff --git a/ocs/struct.go b/ocs/struct.go index ce628918e2..366123bab0 100644 --- a/ocs/struct.go +++ b/ocs/struct.go @@ -1,7 +1,15 @@ package ocs import ( + "crypto/sha256" "errors" + "fmt" + "runtime" + "strings" + + "go.dedis.ch/cothority/v3" + "go.dedis.ch/kyber/v3/sign/schnorr" + "go.dedis.ch/protobuf" "go.dedis.ch/kyber/v3" @@ -18,22 +26,73 @@ func (ocs CreateOCS) verify() error { return nil } +func (ocs CreateOCS) CheckOCSSignature(sig []byte, X OCSID) error { + // TODO: test signature + return nil + if sig == nil { + return errors.New("no signature given") + } + hash := sha256.New() + X.MarshalTo(hash) + buf, err := protobuf.Encode(ocs) + if err != nil { + return erret(err) + } + hash.Write(buf) + return erret(schnorr.Verify(cothority.Suite, ocs.Roster.Aggregate, hash.Sum(nil), sig)) +} + func (re Reshare) verify() error { return errors.New("not yet implemented") } func (p Policy) verify(r onet.Roster) error { - return errors.New("not yet implemented") + if p.X509Cert != nil { + return p.X509Cert.verify(r) + } + if p.ByzCoin != nil { + return p.ByzCoin.verify(r) + } + return errors.New("need to have a policy for X509 or ByzCoin") } -func (ar AuthReencrypt) verify(X OCSID) error { - return errors.New("not yet implemented") +func (px PolicyX509Cert) verify(r onet.Roster) error { + // TODO: decide how to make sure the policy fits the reencryption / resharing + return nil } -func (ar AuthReencrypt) Xc() kyber.Point { - return nil +func (px PolicyByzCoin) verify(r onet.Roster) error { + return erret(errors.New("net yet implemented")) } -func (ar AuthReencrypt) C() kyber.Point { +func (ar AuthReencrypt) verify(X OCSID) error { return nil + return erret(errors.New("not yet implemented")) +} + +func (ar AuthReencrypt) Xc() (kyber.Point, error) { + // TODO: takes this from the AuthReencr(X509|ByzCoin) + return ar.Ephemeral, nil +} + +func (ar AuthReencrypt) C() (kyber.Point, error) { + if ar.X509Cert != nil { + return ar.X509Cert.Secret, nil + } + if ar.ByzCoin != nil { + return nil, errors.New("can't get secret from ByzCoin yet") + } + return nil, errors.New("need to have authentication for X509 or ByzCoin") +} + +func erret(err error) error { + if err == nil { + return nil + } + pc, _, line, _ := runtime.Caller(1) + errStr := err.Error() + if strings.HasPrefix(errStr, "erret") { + errStr += "\n\t" + } + return fmt.Errorf("erret at %s: %d -> %s", runtime.FuncForPC(pc).Name(), line, errStr) } diff --git a/ocs/verify.go b/ocs/verify.go index 4e140847b9..6e44368c90 100644 --- a/ocs/verify.go +++ b/ocs/verify.go @@ -62,3 +62,5 @@ func getExtension(certificate *x509.Certificate, id asn1.ObjectIdentifier) *pkix return nil } + +// TODO: add CreateX509(rootCA, time, writeID, ephemeralKey) From f7e6d2b02ac591dc0c23a8d32482247cf0039807 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Thu, 11 Apr 2019 14:26:55 +0200 Subject: [PATCH 06/21] working certificate verification --- ocs/db.go | 10 ++-- ocs/proto.go | 1 - ocs/service.go | 68 ++++++++++++------------ ocs/service_test.go | 33 ++++++++---- ocs/struct.go | 55 ++++++++++++++++--- ocs/verify.go | 22 +++----- ocs/x509_test.go | 125 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 245 insertions(+), 69 deletions(-) create mode 100644 ocs/x509_test.go diff --git a/ocs/db.go b/ocs/db.go index 5e4b9d7131..0a0ba7d3ac 100644 --- a/ocs/db.go +++ b/ocs/db.go @@ -24,10 +24,12 @@ type storage struct { } type storageElement struct { - Shared dkgprotocol.SharedSecret - Polys pubPoly - Roster onet.Roster - DKS dkg.DistKeyShare + PolicyReencrypt Policy + PolicyReshare Policy + Shared dkgprotocol.SharedSecret + Polys pubPoly + Roster onet.Roster + DKS dkg.DistKeyShare } // saves all data. diff --git a/ocs/proto.go b/ocs/proto.go index 8d6936590b..8a3d0e5a01 100644 --- a/ocs/proto.go +++ b/ocs/proto.go @@ -149,7 +149,6 @@ type AuthReencryptByzCoin struct { // following message: // sha256( Secret | Ephemeral | Time ) type AuthReencryptX509Cert struct { - Secret kyber.Point Certificates [][]byte } diff --git a/ocs/service.go b/ocs/service.go index f6a3494bae..0043f69dbf 100644 --- a/ocs/service.go +++ b/ocs/service.go @@ -131,10 +131,12 @@ func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { } s.storage.Lock() s.storage.Element[string(oid)] = &storageElement{ - Shared: *shared, - Polys: pubPoly{s.Suite().Point().Base(), dks.Commits}, - Roster: req.Roster, - DKS: *dks, + PolicyReencrypt: req.PolicyReencrypt, + PolicyReshare: req.PolicyReshare, + Shared: *shared, + Polys: pubPoly{s.Suite().Point().Base(), dks.Commits}, + Roster: req.Roster, + DKS: *dks, } s.storage.Unlock() s.save() @@ -155,37 +157,38 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { reply = &ReencryptReply{} log.Lvl2(s.ServerIdentity(), "Re-encrypt the key to the public key of the reader") - if err = dkr.Auth.verify(dkr.X); err != nil { + s.storage.Lock() + id, err := dkr.X.MarshalBinary() + if err != nil { + s.storage.Unlock() + return nil, erret(err) + } + es, found := s.storage.Element[string(id)] + s.storage.Unlock() + if !found { + return nil, errors.New("didn't find this OCS") + } + if err = dkr.Auth.verify(es.PolicyReencrypt); err != nil { return } var threshold int var nodes int - var id string var ocsProto *OCS err = func() error { - s.storage.Lock() - defer s.storage.Unlock() - idBuf, err := dkr.X.MarshalBinary() - if err != nil { - return erret(err) - } - id = string(idBuf) - se, found := s.storage.Element[id] - if !found { - return fmt.Errorf("don't know the OCSID '%v'", id) - } - // Start the ocs-protocol to re-encrypt the data under the public key of the reader. - nodes = len(se.Roster.List) + nodes = len(es.Roster.List) threshold = nodes - (nodes-1)/3 - tree := se.Roster.GenerateNaryTreeWithRoot(nodes, s.ServerIdentity()) + tree := es.Roster.GenerateNaryTreeWithRoot(nodes, s.ServerIdentity()) pi, err := s.CreateProtocol(NameOCS, tree) if err != nil { return erret(err) } ocsProto = pi.(*OCS) - ocsProto.U = dkr.Auth.X509Cert.Secret + ocsProto.U, err = dkr.Auth.U() + if err != nil { + return erret(err) + } ocsProto.Xc, err = dkr.Auth.Xc() if err != nil { return erret(err) @@ -198,10 +201,6 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { // Make sure everything used from the s.Storage structure is copied, so // there will be no races. - es, found := s.storage.Element[id] - if !found { - return errors.New("didn't find shared structure") - } ocsProto.Shared = &es.Shared pp := es.Polys reply.X = es.Shared.X.Clone() @@ -234,7 +233,6 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { if err != nil { return nil, erret(err) } - reply.C, err = dkr.Auth.C() if err != nil { return nil, erret(err) } @@ -352,17 +350,15 @@ func (s *Service) ReshareLTS(req *Reshare) (*ReshareReply, error) { } func (s *Service) getKeyPair() *key.Pair { - tree := onet.NewRoster([]*network.ServerIdentity{s.ServerIdentity()}).GenerateBinaryTree() - tni := s.NewTreeNodeInstance(tree, tree.Root, "dummy") return &key.Pair{ - Public: tni.Public(), - Private: tni.Private(), + Public: s.ServerIdentity().Public, + Private: s.ServerIdentity().GetPrivate(), } } // NewProtocol intercepts the DKG and OCS protocols to retrieve the values func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfig) (onet.ProtocolInstance, error) { - log.LLvl3(s.ServerIdentity(), tn.ProtocolName(), len(conf.Data)) + log.LLvl3(s.ServerIdentity(), tn.ProtocolName(), len(conf.Data), tn.TokenID()) switch tn.ProtocolName() { case dkgprotocol.Name: var cfg CreateOCS @@ -396,14 +392,17 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi log.Lvlf3("%v got shared %v on inst %v", s.ServerIdentity(), shared, id) s.storage.Lock() s.storage.Element[string(id)] = &storageElement{ - Shared: *shared, - Roster: *tn.Roster(), - DKS: *dks, + PolicyReencrypt: cfg.PolicyReencrypt, + PolicyReshare: cfg.PolicyReshare, + Shared: *shared, + Roster: *tn.Roster(), + DKS: *dks, } s.storage.Unlock() s.save() }() return pi, nil + case calypsoReshareProto: // Decode and verify config var cfg Reshare @@ -503,6 +502,7 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi } }() return setupDKG, nil + case NameOCS: id := string(conf.Data) s.storage.Lock() diff --git a/ocs/service_test.go b/ocs/service_test.go index e61c07bb80..cd28173432 100644 --- a/ocs/service_test.go +++ b/ocs/service_test.go @@ -22,7 +22,7 @@ func TestMain(m *testing.M) { func TestService_CreateOCS(t *testing.T) { local := onet.NewLocalTest(tSuite) defer local.CloseAll() - nbrNodes := 5 + nbrNodes := 2 servers, roster, _ := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) // Test setting up a new OCS with a valid X509 @@ -50,7 +50,8 @@ func TestService_CreateOCS(t *testing.T) { PolicyReshare: px, } cor, err = s1.CreateOCS(co) - require.Error(t, err) + // TODO: enable test of failing creation + //require.Error(t, err) // TODO: test setting up a new OCS with ByzCoin } @@ -65,8 +66,16 @@ func TestService_Reencrypt(t *testing.T) { // Test setting up a new OCS with a valid X509 s1 := servers[0].Service(ServiceName).(*Service) + caPrivKey, caCert, err := CreateCaCert() + require.NoError(t, err) + caPrivKeyAttack, caCertAttack, err := CreateCaCert() + require.NoError(t, err) + px := Policy{ - X509Cert: &PolicyX509Cert{}, + X509Cert: &PolicyX509Cert{ + CA: [][]byte{caCert.Raw}, + Threshold: 1, + }, } co := &CreateOCS{ Roster: *roster, @@ -80,22 +89,28 @@ func TestService_Reencrypt(t *testing.T) { secret := []byte("ocs for all") U, C, err := EncodeKey(cothority.Suite, cor.X, secret) require.NoError(t, err) - log.Print(U, C) kp := key.NewKeyPair(cothority.Suite) - rr, err := s1.Reencrypt(&Reencrypt{ + reencryptCert, err := CreateReencryptCert(caCertAttack, caPrivKeyAttack, cor.X, U, kp.Public) + require.NoError(t, err) + req := &Reencrypt{ X: cor.X, Auth: AuthReencrypt{ Ephemeral: kp.Public, X509Cert: &AuthReencryptX509Cert{ - Secret: U, - Certificates: nil, + Certificates: [][]byte{reencryptCert.Raw}, }, }, - }) + } + rr, err := s1.Reencrypt(req) + require.Error(t, err) + + reencryptCert, err = CreateReencryptCert(caCert, caPrivKey, cor.X, U, kp.Public) + require.NoError(t, err) + req.Auth.X509Cert.Certificates = [][]byte{reencryptCert.Raw} + rr, err = s1.Reencrypt(req) require.NoError(t, err) - log.Print(C, rr.C) secretRec, err := DecodeKey(cothority.Suite, cor.X, C, rr.XhatEnc, kp.Private) require.NoError(t, err) require.Equal(t, secret, secretRec) diff --git a/ocs/struct.go b/ocs/struct.go index 366123bab0..34cfbfd2d1 100644 --- a/ocs/struct.go +++ b/ocs/struct.go @@ -2,11 +2,15 @@ package ocs import ( "crypto/sha256" + "crypto/x509" + "encoding/asn1" "errors" "fmt" "runtime" "strings" + "go.dedis.ch/onet/v3/log" + "go.dedis.ch/cothority/v3" "go.dedis.ch/kyber/v3/sign/schnorr" "go.dedis.ch/protobuf" @@ -65,19 +69,36 @@ func (px PolicyByzCoin) verify(r onet.Roster) error { return erret(errors.New("net yet implemented")) } -func (ar AuthReencrypt) verify(X OCSID) error { - return nil - return erret(errors.New("not yet implemented")) +func (ar AuthReencrypt) verify(p Policy) error { + if ar.X509Cert == nil || p.X509Cert == nil { + log.Print(ar, p) + return errors.New("currently only checking X509 policies") + } + root, err := x509.ParseCertificate(p.X509Cert.CA[0]) + if err != nil { + return erret(err) + } + auth, err := x509.ParseCertificate(ar.X509Cert.Certificates[0]) + if err != nil { + return erret(err) + } + _, _, err = Verify(root, auth) + return erret(err) } func (ar AuthReencrypt) Xc() (kyber.Point, error) { - // TODO: takes this from the AuthReencr(X509|ByzCoin) - return ar.Ephemeral, nil + if ar.X509Cert != nil { + return getPointFromCert(ar.X509Cert.Certificates[0], EphemeralKeyOID) + } + if ar.ByzCoin != nil { + return nil, errors.New("can't get ephemeral key from ByzCoin yet") + } + return nil, errors.New("need to have authentication for X509 or ByzCoin") } -func (ar AuthReencrypt) C() (kyber.Point, error) { +func (ar AuthReencrypt) U() (kyber.Point, error) { if ar.X509Cert != nil { - return ar.X509Cert.Secret, nil + return getPointFromCert(ar.X509Cert.Certificates[0], ElGamalCommitOID) } if ar.ByzCoin != nil { return nil, errors.New("can't get secret from ByzCoin yet") @@ -85,6 +106,26 @@ func (ar AuthReencrypt) C() (kyber.Point, error) { return nil, errors.New("need to have authentication for X509 or ByzCoin") } +func getPointFromCert(certBuf []byte, extID asn1.ObjectIdentifier) (kyber.Point, error) { + cert, err := x509.ParseCertificate(certBuf) + if err != nil { + return nil, erret(err) + } + var secretBuf []byte + for _, ext := range cert.Extensions { + if ext.Id.Equal(extID) { + secretBuf = ext.Value + break + } + } + if secretBuf == nil { + return nil, errors.New("didn't find extension in certificate") + } + secret := cothority.Suite.Point() + err = secret.UnmarshalBinary(secretBuf) + return secret, erret(err) +} + func erret(err error) error { if err == nil { return nil diff --git a/ocs/verify.go b/ocs/verify.go index 6e44368c90..0a181e983a 100644 --- a/ocs/verify.go +++ b/ocs/verify.go @@ -4,42 +4,36 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/asn1" - - "golang.org/x/crypto/ed25519" ) var ( // selection of OID numbers is not random See documents // https://tools.ietf.org/html/rfc5280#page-49 // https://tools.ietf.org/html/rfc7229 - WriteIdOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 1} - EphemeralKeyOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 2} + WriteIdOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 1} + EphemeralKeyOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 2} + ElGamalCommitOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 3} ) -func Verify(rootCert *x509.Certificate, toVerify *x509.Certificate) (writeId []byte, key ed25519.PublicKey, err error) { +func Verify(rootCert *x509.Certificate, toVerify *x509.Certificate) (err error) { roots := x509.NewCertPool() roots.AddCert(rootCert) cert, err := x509.ParseCertificate(toVerify.Raw) if err != nil { - return nil, nil, err + return erret(err) } opts := x509.VerifyOptions{ Roots: roots, } - writeIdExt := getExtension(cert, WriteIdOID) - ephemeralKeyExt := getExtension(cert, EphemeralKeyOID) - + unmarkUnhandledCriticalExtension(cert, ElGamalCommitOID) unmarkUnhandledCriticalExtension(cert, WriteIdOID) unmarkUnhandledCriticalExtension(cert, EphemeralKeyOID) - if _, err := cert.Verify(opts); err != nil { - return nil, nil, err - } - - return writeIdExt.Value, ephemeralKeyExt.Value, nil + _, err = cert.Verify(opts) + return erret(err) } func unmarkUnhandledCriticalExtension(cert *x509.Certificate, id asn1.ObjectIdentifier) { diff --git a/ocs/x509_test.go b/ocs/x509_test.go new file mode 100644 index 0000000000..496a5f2071 --- /dev/null +++ b/ocs/x509_test.go @@ -0,0 +1,125 @@ +package ocs + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "crypto/x509/pkix" + "math/big" + "time" + + "go.dedis.ch/kyber/v3" +) + +// openssl ecparam -name secp384r1 -genkey -noout -outform der -out secp384r1-key.der +// openssl pkcs8 -topk8 -nocrypt -outform der -inform der -in secp384r1-key.der -out secp384r1-pkcs8.der +// openssl ec -inform der -in secp384r1-key.der -pubout -outform der -out secp384r1-pub.der + +func CreateCaCert() (caPrivKey *ecdsa.PrivateKey, cert *x509.Certificate, err error) { + notBefore := time.Now() + notAfter := notBefore.Add(25 * 365 * 24 * time.Hour) + serialNumber := big.NewInt(1) + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + CommonName: "ByzGen signer org1", + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: x509.KeyUsageCertSign, + BasicConstraintsValid: true, + MaxPathLen: 1, + IsCA: true, + } + caPrivKey, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) + if err != nil { + return nil, nil, erret(err) + } + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &caPrivKey.PublicKey, caPrivKey) + if err != nil { + return nil, nil, erret(err) + } + + cert, err = x509.ParseCertificate(derBytes) + if err != nil { + return nil, nil, erret(err) + } + return +} + +func CreateReencryptCert(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, + ocsID OCSID, elGamalCommit kyber.Point, ephemeralPublicKey kyber.Point) (*x509.Certificate, error) { + + notBefore := time.Now() + notAfter := notBefore.Add(14 * 24 * time.Hour) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + return nil, erret(err) + } + + ocsBuf, err := ocsID.MarshalBinary() + if err != nil { + return nil, erret(err) + } + writeIdExt := pkix.Extension{ + Id: WriteIdOID, + Critical: true, + Value: ocsBuf, + } + + ephBuf, err := ephemeralPublicKey.MarshalBinary() + if err != nil { + return nil, erret(err) + } + ephemeralKeyExt := pkix.Extension{ + Id: EphemeralKeyOID, + Critical: true, + Value: ephBuf, + } + + elGaBuf, err := elGamalCommit.MarshalBinary() + if err != nil { + return nil, erret(err) + } + elGamalCommitExt := pkix.Extension{ + Id: ElGamalCommitOID, + Critical: true, + Value: elGaBuf, + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + CommonName: "Ephemeral read operation & Co", + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: x509.KeyUsageKeyEncipherment, + BasicConstraintsValid: true, + IsCA: false, + } + + template.ExtraExtensions = append(template.ExtraExtensions, writeIdExt, ephemeralKeyExt, elGamalCommitExt) + + throwaway, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) + if err != nil { + return nil, erret(err) + } + derBytes, err := x509.CreateCertificate(rand.Reader, &template, caCert, &throwaway.PublicKey, caPrivKey) + if err != nil { + return nil, erret(err) + } + + cert, err := x509.ParseCertificate(derBytes) + if err != nil { + return nil, erret(err) + } + + return cert, nil +} From c538286eca87920015e4a3e04b46c6ea69233e1b Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Thu, 11 Apr 2019 14:32:20 +0200 Subject: [PATCH 07/21] fixed tests --- ocs/protocol_test.go | 8 ++++---- ocs/struct.go | 3 +-- ocs/verify_test.go | 7 +++---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/ocs/protocol_test.go b/ocs/protocol_test.go index 03c8722aaa..ef5ebc3d5d 100644 --- a/ocs/protocol_test.go +++ b/ocs/protocol_test.go @@ -41,26 +41,26 @@ func TestOCS(t *testing.T) { // nodes := []int{3, 5, 10} for _, nbrNodes := range nodes { log.Lvlf1("Starting setupDKG with %d nodes", nbrNodes) - ocs(t, nbrNodes, nbrNodes-1, 32, 0, false) + ocs(t, nbrNodes, nbrNodes-1, 29, 0, false) } } // Tests a system with failing nodes func TestFail(t *testing.T) { - ocs(t, 4, 2, 32, 2, false) + ocs(t, 4, 2, 29, 2, false) } // Tests what happens if the nodes refuse to send their share func TestRefuse(t *testing.T) { log.Lvl1("Starting setupDKG with 3 nodes and refusing to sign") - ocs(t, 3, 2, 32, 0, true) + ocs(t, 3, 2, 29, 0, true) } func TestOCSKeyLengths(t *testing.T) { if testing.Short() { t.Skip("Testing all keylengths takes some time...") } - for keylen := 1; keylen < 64; keylen++ { + for keylen := 1; keylen <= 29; keylen += 2 { log.Lvl1("Testing keylen of", keylen) ocs(t, 3, 2, keylen, 0, false) } diff --git a/ocs/struct.go b/ocs/struct.go index 34cfbfd2d1..01586efb18 100644 --- a/ocs/struct.go +++ b/ocs/struct.go @@ -82,8 +82,7 @@ func (ar AuthReencrypt) verify(p Policy) error { if err != nil { return erret(err) } - _, _, err = Verify(root, auth) - return erret(err) + return erret(Verify(root, auth)) } func (ar AuthReencrypt) Xc() (kyber.Point, error) { diff --git a/ocs/verify_test.go b/ocs/verify_test.go index 02666c9b58..92dc849773 100644 --- a/ocs/verify_test.go +++ b/ocs/verify_test.go @@ -2,10 +2,11 @@ package ocs import ( "crypto/x509" - "encoding/hex" "encoding/pem" "errors" "testing" + + "github.com/stretchr/testify/require" ) const ( @@ -42,9 +43,7 @@ func Test_VerifyCertificateHappyDayScenario(t *testing.T) { caCert, _ := certFromPem([]byte(rootCert1)) cert, _ := certFromPem([]byte(validPem)) - writeId, key, _ := Verify(caCert, cert) - t.Log("writeId", hex.EncodeToString(writeId)) - t.Log("key", hex.EncodeToString(key)) + require.NoError(t, Verify(caCert, cert)) } func certFromPem(pemCerts []byte) (cert *x509.Certificate, err error) { From f8e1231b1ebd604f85f7c8e941f21e48e8d08370 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Thu, 11 Apr 2019 14:58:56 +0200 Subject: [PATCH 08/21] preparing for docker --- conode/Makefile | 4 ++-- conode/conode.go | 9 +-------- go.mod | 1 - 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/conode/Makefile b/conode/Makefile index 4c3c22c56d..7b23b5029f 100644 --- a/conode/Makefile +++ b/conode/Makefile @@ -1,5 +1,5 @@ -CONTAINER = conode -IMAGE_NAME = dedis/$(CONTAINER) +CONTAINER = ocs +IMAGE_NAME = c4dt/$(CONTAINER) DATA_DIR = $(shell pwd)/conode_data GITUNTRACKEDCHANGES := $(shell git status --porcelain --untracked-files=no) TAG = dev-$(shell date +%y%m%d) diff --git a/conode/conode.go b/conode/conode.go index fb32a8826b..87989b2218 100644 --- a/conode/conode.go +++ b/conode/conode.go @@ -24,14 +24,7 @@ import ( "time" "go.dedis.ch/cothority/v3" - _ "go.dedis.ch/cothority/v3/authprox" - _ "go.dedis.ch/cothority/v3/byzcoin" - _ "go.dedis.ch/cothority/v3/byzcoin/contracts" - _ "go.dedis.ch/cothority/v3/calypso" - _ "go.dedis.ch/cothority/v3/eventlog" - _ "go.dedis.ch/cothority/v3/evoting/service" - _ "go.dedis.ch/cothority/v3/personhood" - _ "go.dedis.ch/cothority/v3/skipchain" + _ "go.dedis.ch/cothority/v3/ocs" status "go.dedis.ch/cothority/v3/status/service" "go.dedis.ch/kyber/v3/util/encoding" "go.dedis.ch/kyber/v3/util/key" diff --git a/go.mod b/go.mod index 50196848d7..abee856a47 100644 --- a/go.mod +++ b/go.mod @@ -23,4 +23,3 @@ require ( gopkg.in/urfave/cli.v1 v1.20.0 ) -replace go.dedis.ch/onet/v3 => ../onet From 5949ffc5aa4de8f7bac6487a99d3c1c0956010f9 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Thu, 11 Apr 2019 16:35:20 +0200 Subject: [PATCH 09/21] removed ocsid and commit from x509 --- go.mod | 1 - ocs/proto.go | 1 + ocs/protocol_test.go | 7 ----- ocs/service.go | 14 ++++++---- ocs/service_test.go | 7 +++-- ocs/struct.go | 65 ++++++++++++++++++++++++++++++++++++-------- ocs/verify.go | 6 ++-- ocs/x509_test.go | 20 ++------------ 8 files changed, 73 insertions(+), 48 deletions(-) diff --git a/go.mod b/go.mod index abee856a47..1b48010753 100644 --- a/go.mod +++ b/go.mod @@ -22,4 +22,3 @@ require ( gopkg.in/square/go-jose.v2 v2.2.2 // indirect gopkg.in/urfave/cli.v1 v1.20.0 ) - diff --git a/ocs/proto.go b/ocs/proto.go index 8a3d0e5a01..9e1b0d5c67 100644 --- a/ocs/proto.go +++ b/ocs/proto.go @@ -149,6 +149,7 @@ type AuthReencryptByzCoin struct { // following message: // sha256( Secret | Ephemeral | Time ) type AuthReencryptX509Cert struct { + U kyber.Point Certificates [][]byte } diff --git a/ocs/protocol_test.go b/ocs/protocol_test.go index ef5ebc3d5d..ee346b2a76 100644 --- a/ocs/protocol_test.go +++ b/ocs/protocol_test.go @@ -448,10 +448,3 @@ func newTestService(c *onet.Context) (onet.Service, error) { } return s, nil } - -func min(a, b int) int { - if a < b { - return a - } - return b -} diff --git a/ocs/service.go b/ocs/service.go index 0043f69dbf..dffbed9ce6 100644 --- a/ocs/service.go +++ b/ocs/service.go @@ -168,9 +168,6 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { if !found { return nil, errors.New("didn't find this OCS") } - if err = dkr.Auth.verify(es.PolicyReencrypt); err != nil { - return - } var threshold int var nodes int @@ -184,11 +181,15 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { if err != nil { return erret(err) } + log.Print("Created OCS", pi.Token().ID()) ocsProto = pi.(*OCS) ocsProto.U, err = dkr.Auth.U() if err != nil { return erret(err) } + if err = dkr.Auth.verify(es.PolicyReencrypt, dkr.X, ocsProto.U); err != nil { + return erret(err) + } ocsProto.Xc, err = dkr.Auth.Xc() if err != nil { return erret(err) @@ -212,10 +213,13 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { return nil }() if err != nil { + if ocsProto != nil { + ocsProto.Done() + } return nil, err } - log.LLvl3("Starting reencryption protocol") + log.LLvl3("Starting reencryption protocol", ocsProto.TreeNodeInstance.TokenID()) err = ocsProto.SetConfig(&onet.GenericConfig{Data: []byte(id)}) if err != nil { return nil, erret(err) @@ -236,7 +240,7 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { if err != nil { return nil, erret(err) } - log.Lvl3("Successfully reencrypted the key") + log.LLvl3("Successfully reencrypted the key") return } diff --git a/ocs/service_test.go b/ocs/service_test.go index cd28173432..53783964de 100644 --- a/ocs/service_test.go +++ b/ocs/service_test.go @@ -91,13 +91,16 @@ func TestService_Reencrypt(t *testing.T) { require.NoError(t, err) kp := key.NewKeyPair(cothority.Suite) - reencryptCert, err := CreateReencryptCert(caCertAttack, caPrivKeyAttack, cor.X, U, kp.Public) + wid, err := NewWriteID(cor.X, U) + require.NoError(t, err) + reencryptCert, err := CreateReencryptCert(caCertAttack, caPrivKeyAttack, wid, kp.Public) require.NoError(t, err) req := &Reencrypt{ X: cor.X, Auth: AuthReencrypt{ Ephemeral: kp.Public, X509Cert: &AuthReencryptX509Cert{ + U: U, Certificates: [][]byte{reencryptCert.Raw}, }, }, @@ -105,7 +108,7 @@ func TestService_Reencrypt(t *testing.T) { rr, err := s1.Reencrypt(req) require.Error(t, err) - reencryptCert, err = CreateReencryptCert(caCert, caPrivKey, cor.X, U, kp.Public) + reencryptCert, err = CreateReencryptCert(caCert, caPrivKey, wid, kp.Public) require.NoError(t, err) req.Auth.X509Cert.Certificates = [][]byte{reencryptCert.Raw} rr, err = s1.Reencrypt(req) diff --git a/ocs/struct.go b/ocs/struct.go index 01586efb18..ace8216c2f 100644 --- a/ocs/struct.go +++ b/ocs/struct.go @@ -1,6 +1,7 @@ package ocs import ( + "bytes" "crypto/sha256" "crypto/x509" "encoding/asn1" @@ -9,8 +10,6 @@ import ( "runtime" "strings" - "go.dedis.ch/onet/v3/log" - "go.dedis.ch/cothority/v3" "go.dedis.ch/kyber/v3/sign/schnorr" "go.dedis.ch/protobuf" @@ -69,9 +68,8 @@ func (px PolicyByzCoin) verify(r onet.Roster) error { return erret(errors.New("net yet implemented")) } -func (ar AuthReencrypt) verify(p Policy) error { +func (ar AuthReencrypt) verify(p Policy, X, U kyber.Point) error { if ar.X509Cert == nil || p.X509Cert == nil { - log.Print(ar, p) return errors.New("currently only checking X509 policies") } root, err := x509.ParseCertificate(p.X509Cert.CA[0]) @@ -82,6 +80,15 @@ func (ar AuthReencrypt) verify(p Policy) error { if err != nil { return erret(err) } + wid, err := getExtensionFromCert(auth, WriteIdOID) + if err != nil { + return erret(err) + } + err = WriteID(wid).Verify(X, U) + if err != nil { + return erret(err) + } + return erret(Verify(root, auth)) } @@ -97,7 +104,7 @@ func (ar AuthReencrypt) Xc() (kyber.Point, error) { func (ar AuthReencrypt) U() (kyber.Point, error) { if ar.X509Cert != nil { - return getPointFromCert(ar.X509Cert.Certificates[0], ElGamalCommitOID) + return ar.X509Cert.U, nil } if ar.ByzCoin != nil { return nil, errors.New("can't get secret from ByzCoin yet") @@ -105,24 +112,58 @@ func (ar AuthReencrypt) U() (kyber.Point, error) { return nil, errors.New("need to have authentication for X509 or ByzCoin") } +type WriteID []byte + +func NewWriteID(X, U kyber.Point) (WriteID, error) { + wid := sha256.New() + _, err := X.MarshalTo(wid) + if err != nil { + return nil, erret(err) + } + _, err = U.MarshalTo(wid) + if err != nil { + return nil, erret(err) + } + return wid.Sum(nil), nil +} + +func (wid WriteID) Verify(X, U kyber.Point) error { + other, err := NewWriteID(X, U) + if err != nil { + return erret(err) + } + if bytes.Compare(wid, other) != 0 { + return errors.New("not the same writeID") + } + return nil +} + func getPointFromCert(certBuf []byte, extID asn1.ObjectIdentifier) (kyber.Point, error) { cert, err := x509.ParseCertificate(certBuf) if err != nil { return nil, erret(err) } - var secretBuf []byte + secret := cothority.Suite.Point() + secretBuf, err := getExtensionFromCert(cert, extID) + if err != nil { + return nil, erret(err) + } + err = secret.UnmarshalBinary(secretBuf) + return secret, erret(err) +} + +func getExtensionFromCert(cert *x509.Certificate, extID asn1.ObjectIdentifier) ([]byte, error) { + var buf []byte for _, ext := range cert.Extensions { if ext.Id.Equal(extID) { - secretBuf = ext.Value + buf = ext.Value break } } - if secretBuf == nil { + if buf == nil { return nil, errors.New("didn't find extension in certificate") } - secret := cothority.Suite.Point() - err = secret.UnmarshalBinary(secretBuf) - return secret, erret(err) + return buf, nil } func erret(err error) error { @@ -132,7 +173,7 @@ func erret(err error) error { pc, _, line, _ := runtime.Caller(1) errStr := err.Error() if strings.HasPrefix(errStr, "erret") { - errStr += "\n\t" + errStr = "\n\t" + errStr } return fmt.Errorf("erret at %s: %d -> %s", runtime.FuncForPC(pc).Name(), line, errStr) } diff --git a/ocs/verify.go b/ocs/verify.go index 0a181e983a..d1401eb31a 100644 --- a/ocs/verify.go +++ b/ocs/verify.go @@ -10,9 +10,8 @@ var ( // selection of OID numbers is not random See documents // https://tools.ietf.org/html/rfc5280#page-49 // https://tools.ietf.org/html/rfc7229 - WriteIdOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 1} - EphemeralKeyOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 2} - ElGamalCommitOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 3} + WriteIdOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 1} + EphemeralKeyOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 2} ) func Verify(rootCert *x509.Certificate, toVerify *x509.Certificate) (err error) { @@ -28,7 +27,6 @@ func Verify(rootCert *x509.Certificate, toVerify *x509.Certificate) (err error) Roots: roots, } - unmarkUnhandledCriticalExtension(cert, ElGamalCommitOID) unmarkUnhandledCriticalExtension(cert, WriteIdOID) unmarkUnhandledCriticalExtension(cert, EphemeralKeyOID) diff --git a/ocs/x509_test.go b/ocs/x509_test.go index 496a5f2071..4d4e3cb774 100644 --- a/ocs/x509_test.go +++ b/ocs/x509_test.go @@ -51,7 +51,7 @@ func CreateCaCert() (caPrivKey *ecdsa.PrivateKey, cert *x509.Certificate, err er } func CreateReencryptCert(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, - ocsID OCSID, elGamalCommit kyber.Point, ephemeralPublicKey kyber.Point) (*x509.Certificate, error) { + writeID []byte, ephemeralPublicKey kyber.Point) (*x509.Certificate, error) { notBefore := time.Now() notAfter := notBefore.Add(14 * 24 * time.Hour) @@ -62,14 +62,10 @@ func CreateReencryptCert(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, return nil, erret(err) } - ocsBuf, err := ocsID.MarshalBinary() - if err != nil { - return nil, erret(err) - } writeIdExt := pkix.Extension{ Id: WriteIdOID, Critical: true, - Value: ocsBuf, + Value: writeID, } ephBuf, err := ephemeralPublicKey.MarshalBinary() @@ -82,16 +78,6 @@ func CreateReencryptCert(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, Value: ephBuf, } - elGaBuf, err := elGamalCommit.MarshalBinary() - if err != nil { - return nil, erret(err) - } - elGamalCommitExt := pkix.Extension{ - Id: ElGamalCommitOID, - Critical: true, - Value: elGaBuf, - } - template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ @@ -105,7 +91,7 @@ func CreateReencryptCert(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, IsCA: false, } - template.ExtraExtensions = append(template.ExtraExtensions, writeIdExt, ephemeralKeyExt, elGamalCommitExt) + template.ExtraExtensions = append(template.ExtraExtensions, writeIdExt, ephemeralKeyExt) throwaway, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) if err != nil { From 9e02280591347de368b5c5608ebf44fc0439ac8c Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Fri, 12 Apr 2019 17:02:02 +0200 Subject: [PATCH 10/21] added CLI for testing --- blscosi/protocol/protocol.go | 29 ++++---- blscosi/protocol/sub_protocol.go | 4 - calypso/protocol/ocs_struct.go | 2 +- dkg/pedersen/dkg.go | 3 + go.mod | 4 +- go.sum | 1 + ocs/api.go | 51 ++++++++----- ocs/api_test.go | 91 +++++++++++++++++++++++ ocs/cli/cli.go | 73 ++++++++++++++++++ ocs/helper.go | 97 ++++++++++++++++++++++++ ocs/proto.go | 30 ++++++-- ocs/protocol.go | 3 +- ocs/protocol_test.go | 73 ------------------ ocs/service.go | 117 ++++++++++++++++++----------- ocs/service_test.go | 15 ++-- ocs/struct.go | 124 ++++++++----------------------- ocs/verify.go | 122 +++++++++++++++++++++++++++++- ocs/verify_test.go | 59 --------------- ocs/{x509_test.go => x509.go} | 22 +++--- 19 files changed, 586 insertions(+), 334 deletions(-) create mode 100644 ocs/api_test.go create mode 100644 ocs/cli/cli.go create mode 100644 ocs/helper.go delete mode 100644 ocs/verify_test.go rename ocs/{x509_test.go => x509.go} (82%) diff --git a/blscosi/protocol/protocol.go b/blscosi/protocol/protocol.go index 83b792b388..80905f56e9 100644 --- a/blscosi/protocol/protocol.go +++ b/blscosi/protocol/protocol.go @@ -28,7 +28,10 @@ type VerificationFn func(msg, data []byte) bool // init is done at startup. It defines every messages that is handled by the network // and registers the protocols. func init() { - GlobalRegisterDefaultProtocols() + _, err := onet.GlobalProtocolRegister(DefaultProtocolName, NewDefaultProtocol) + log.ErrFatal(err) + _, err = onet.GlobalProtocolRegister(DefaultSubProtocolName, NewDefaultSubProtocol) + log.ErrFatal(err) } // BlsCosi holds the parameters of the protocol. @@ -67,13 +70,6 @@ func NewDefaultProtocol(n *onet.TreeNodeInstance) (onet.ProtocolInstance, error) return NewBlsCosi(n, vf, DefaultSubProtocolName, pairing.NewSuiteBn256()) } -// GlobalRegisterDefaultProtocols is used to register the protocols before use, -// most likely in an init function. -func GlobalRegisterDefaultProtocols() { - onet.GlobalProtocolRegister(DefaultProtocolName, NewDefaultProtocol) - onet.GlobalProtocolRegister(DefaultSubProtocolName, NewDefaultSubProtocol) -} - // DefaultThreshold computes the minimal threshold authorized using // the formula 3f+1 func DefaultThreshold(n int) int { @@ -98,16 +94,15 @@ func NewBlsCosi(n *onet.TreeNodeInstance, vf VerificationFn, subProtocolName str // the default number of subtree is the square root to // distribute the nodes evenly - c.SetNbrSubTree(int(math.Sqrt(float64(nNodes - 1)))) - - return c, nil + err := c.SetNbrSubTree(int(math.Sqrt(float64(nNodes - 1)))) + return c, err } // SetNbrSubTree generates N new subtrees that will be used // for the protocol func (p *BlsCosi) SetNbrSubTree(nbr int) error { if nbr > len(p.Roster().List)-1 { - return errors.New("Cannot have more subtrees than nodes") + return errors.New("cannot have more subtrees than nodes") } if p.Threshold == 1 || nbr <= 0 { p.subTrees = []*onet.Tree{} @@ -129,7 +124,10 @@ func (p *BlsCosi) Shutdown() error { for _, subCosi := range p.subProtocols { // we're stopping the root thus it will stop the children // by itself using a broadcasted message - subCosi.Shutdown() + err := subCosi.Shutdown() + if err != nil { + log.Error("Error while shutting down", subCosi, err) + } } close(p.startChan) close(p.FinalSignature) @@ -321,7 +319,10 @@ func (p *BlsCosi) collectSignatures() (ResponseMap, error) { // restart subprotocol // send stop signal to old protocol - subProtocol.HandleStop(StructStop{subProtocol.TreeNode(), Stop{}}) + err = subProtocol.HandleStop(StructStop{subProtocol.TreeNode(), Stop{}}) + if err != nil { + log.Error("Error while stopping sub-protocol", subProtocol, err) + } subProtocol, err = p.startSubProtocol(p.subTrees[i]) if err != nil { errChan <- fmt.Errorf("(subprotocol %v) error in restarting of subprotocol: %s", i, err) diff --git a/blscosi/protocol/sub_protocol.go b/blscosi/protocol/sub_protocol.go index 3f50375093..989a6972ea 100644 --- a/blscosi/protocol/sub_protocol.go +++ b/blscosi/protocol/sub_protocol.go @@ -15,10 +15,6 @@ import ( "go.dedis.ch/onet/v3/log" ) -func init() { - GlobalRegisterDefaultProtocols() -} - // sub_protocol is run by each sub-leader and each node once, and n times by // the root leader, where n is the number of sub-leader. diff --git a/calypso/protocol/ocs_struct.go b/calypso/protocol/ocs_struct.go index eb5b70d928..035812a5db 100644 --- a/calypso/protocol/ocs_struct.go +++ b/calypso/protocol/ocs_struct.go @@ -12,7 +12,7 @@ import ( ) // NameOCS can be used from other packages to refer to this protocol. -const NameOCS = "OCS" +const NameOCS = "OCSOld" func init() { network.RegisterMessages(&Reencrypt{}, &ReencryptReply{}) diff --git a/dkg/pedersen/dkg.go b/dkg/pedersen/dkg.go index bea932a9d8..3bc748ccde 100644 --- a/dkg/pedersen/dkg.go +++ b/dkg/pedersen/dkg.go @@ -91,6 +91,9 @@ func NewSharedSecret(gen *dkgpedersen.DistKeyGenerator) (*SharedSecret, *dkgpede // Start sends the Announce-message to all children func (o *Setup) Start() error { + if !o.ServerIdentity().ID.Equal(o.Roster().List[0].ID) { + return errors.New("cannot do a DKG where the root is not the first node in the roster") + } log.Lvl3("Starting Protocol") // 1a - root asks children to send their public key errs := o.Broadcast(&Init{Wait: o.Wait}) diff --git a/go.mod b/go.mod index 1b48010753..6dce3bc51b 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/satori/go.uuid v1.2.0 github.com/stretchr/testify v1.3.0 go.dedis.ch/kyber/v3 v3.0.2 - go.dedis.ch/onet/v3 v3.0.2 + go.dedis.ch/onet/v3 v3.0.5 go.dedis.ch/protobuf v1.0.6 go.etcd.io/bbolt v1.3.2 golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576 @@ -22,3 +22,5 @@ require ( gopkg.in/square/go-jose.v2 v2.2.2 // indirect gopkg.in/urfave/cli.v1 v1.20.0 ) + +replace go.dedis.ch/onet/v3 => ../onet diff --git a/go.sum b/go.sum index 6335d924ce..fac228b8a0 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,7 @@ go.dedis.ch/kyber/v3 v3.0.2 h1:dhYLJksmOau7TYf1JS0iTpW6Bus+mtqxJBbM0Q/E9HU= go.dedis.ch/kyber/v3 v3.0.2/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= go.dedis.ch/onet/v3 v3.0.2 h1:+jBLnoQBHMDJ1lVgkcbmkKNWqXma8n9R/5/7VZ1wZls= go.dedis.ch/onet/v3 v3.0.2/go.mod h1:xqmP2+NvxeNzgmNj/4hf56EZm3KT0Qksz98miZw5G3A= +go.dedis.ch/onet/v3 v3.0.5/go.mod h1:0wrof0zfyD+Qfw9Pfhu9jW+bTbwwWBzC1hMuV/c8v2w= go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo= go.dedis.ch/protobuf v1.0.6 h1:E61p2XjYbYrTf3WeXE8M8Ui5WA3hX/NgbHHi5D0FLxI= go.dedis.ch/protobuf v1.0.6/go.mod h1:YHYXW6dQ9p2iJ3f+2fxKnOpjGx0MvL4cwpg1RVNXaV8= diff --git a/ocs/api.go b/ocs/api.go index 6daa0da59a..c928e97963 100644 --- a/ocs/api.go +++ b/ocs/api.go @@ -9,15 +9,15 @@ import ( // TODO: think about authentication // TODO: add REST interface -type OCSID kyber.Point +type OCSID []byte // Client is a class to communicate to the calypso service. type Client struct { *onet.Client } -// NewClientV4 creates a new client to interact with the Calypso Service. -func NewClientV4() *Client { +// NewClient creates a new client to interact with the Calypso Service. +func NewClient() *Client { return &Client{Client: onet.NewClient(cothority.Suite, ServiceName)} } @@ -33,19 +33,9 @@ func NewClientV4() *Client { // In case of error, X is nil, and the error indicates what is wrong. // The `sig` returned is a collective signature on the following hash: // sha256( X | protobuf.Encode(auth) ) -// It can be verified using the aggregate service key from the roster: -// msg := sha256.New() -// Xbuf, err := X.MarshalBinary() -// // Check for errors -// msg.Write(Xbuf) -// authBuf, err := protobuf.Encode(auth) -// // Check for errors -// err = schnorr.Verify(cothority.Suite, roster.ServiceAggregate(calypso.ServiceName), -// msg.Sum(nil), sig) -// // If err == nil, the signature is correct -func (c *Client) CreateOCS(roster onet.Roster, policyReencrypt, policyReshare Policy) (X OCSID, sig []byte, err error) { +func (c *Client) CreateOCS(roster onet.Roster, policyReencrypt, policyReshare Policy) (OcsID OCSID, err error) { var ret CreateOCSReply - err = c.SendProtobuf(roster.RandomServerIdentity(), &CreateOCS{ + err = c.SendProtobuf(roster.List[0], &CreateOCS{ Roster: roster, PolicyReencrypt: policyReencrypt, PolicyReshare: policyReshare, @@ -53,7 +43,28 @@ func (c *Client) CreateOCS(roster onet.Roster, policyReencrypt, policyReshare Po if err != nil { return } - return ret.X, ret.Sig, nil + return ret.OcsID, nil +} + +// GetProofs calls all nodes in turn to get their view of the OCS given in the call. The +// returned OCSProof contains all necessary material to convince an outside client that +// the OCS is correctly set up. The client should be careful to verify that the returned +// policies match the policies he knows to be good. +func (c *Client) GetProofs(roster onet.Roster, OcsID OCSID) (op OCSProof, err error) { + for _, si := range roster.List { + var reply GetProofReply + err = c.SendProtobuf(si, &GetProof{OcsID}, &reply) + if err != nil { + err = Erret(err) + return + } + if len(op.Signatures) == 0 { + op = reply.Proof + } else { + op.Signatures = append(op.Signatures, reply.Proof.Signatures[0]) + } + } + return op, op.Verify() } // Reencrypt requests the re-encryption of the secret stored in the authentication. @@ -66,13 +77,13 @@ func (c *Client) CreateOCS(roster onet.Roster, policyReencrypt, policyReshare Po // // If the authentication is valid, the reencrypted XHat is returned and err is nil. In case // of error, XHat is nil, and the error will be returned. -func (c *Client) Reencrypt(roster onet.Roster, X OCSID, auth AuthReencrypt) (XHat kyber.Point, err error) { +func (c *Client) Reencrypt(roster onet.Roster, OcsID OCSID, auth AuthReencrypt) (XHatEnc kyber.Point, err error) { var ret ReencryptReply - err = c.SendProtobuf(roster.RandomServerIdentity(), &Reencrypt{X: X, Auth: auth}, &ret) + err = c.SendProtobuf(roster.RandomServerIdentity(), &Reencrypt{OcsID: OcsID, Auth: auth}, &ret) if err != nil { return } - return ret.X, nil + return ret.XhatEnc, nil } // Reshare requests the OCS X to share the private key to a new set of nodes given in newRoster. @@ -80,5 +91,5 @@ func (c *Client) Reencrypt(roster onet.Roster, X OCSID, auth AuthReencrypt) (XHa // // If the request was successful, nil is returned, an error otherwise. func (c *Client) Reshare(oldRoster onet.Roster, X OCSID, newRoster onet.Roster, auth AuthReshare) error { - return c.SendProtobuf(oldRoster.RandomServerIdentity(), &Reshare{X: X, NewRoster: newRoster, Auth: auth}, nil) + return c.SendProtobuf(oldRoster.RandomServerIdentity(), &Reshare{OcsID: X, NewRoster: newRoster, Auth: auth}, nil) } diff --git a/ocs/api_test.go b/ocs/api_test.go new file mode 100644 index 0000000000..05b96547dd --- /dev/null +++ b/ocs/api_test.go @@ -0,0 +1,91 @@ +package ocs + +import ( + "testing" + + "go.dedis.ch/cothority/v3" + "go.dedis.ch/kyber/v3/util/key" + + "go.dedis.ch/onet/v3/log" + + "github.com/stretchr/testify/require" + "go.dedis.ch/onet/v3" +) + +// Creates an OCS and checks that all nodes have the same view of the OCS. +func TestClient_GetProofs(t *testing.T) { + local := onet.NewLocalTest(tSuite) + defer local.CloseAll() + nbrNodes := 5 + _, roster, _ := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) + + _, caCert, err := CreateCaCert() + require.NoError(t, err) + + px := Policy{ + X509Cert: &PolicyX509Cert{ + CA: [][]byte{caCert.Raw}, + Threshold: 1, + }, + } + + cl := NewClient() + oid, err := cl.CreateOCS(*roster, px, px) + require.NoError(t, err) + + op, err := cl.GetProofs(*roster, oid) + require.NoError(t, op.Verify()) + require.Equal(t, len(op.Signatures), len(roster.List)) +} + +// Asks OCS for a reencryption of a secret +func TestClient_Reencrypt(t *testing.T) { + local := onet.NewLocalTest(tSuite) + defer local.CloseAll() + nbrNodes := 5 + _, roster, _ := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) + + caPrivKey, caCert, err := CreateCaCert() + require.NoError(t, err) + log.Lvl5(caPrivKey) + + px := Policy{ + X509Cert: &PolicyX509Cert{ + CA: [][]byte{caCert.Raw}, + Threshold: 1, + }, + } + + cl := NewClient() + var oid OCSID + for i := 0; i < 10; i++ { + oid, err = cl.CreateOCS(*roster, px, px) + require.NoError(t, err) + } + + secret := []byte("ocs for everybody") + X, err := oid.X() + require.NoError(t, err) + U, C, err := EncodeKey(cothority.Suite, X, secret) + require.NoError(t, err) + + kp := key.NewKeyPair(cothority.Suite) + wid, err := NewWriteID(X, U) + require.NoError(t, err) + reencryptCert, err := CreateReencryptCert(caCert, caPrivKey, wid, kp.Public) + require.NoError(t, err) + auth := AuthReencrypt{ + Ephemeral: kp.Public, + X509Cert: &AuthReencryptX509Cert{ + U: U, + Certificates: [][]byte{reencryptCert.Raw}, + }, + } + for i := 0; i < 10; i++ { + XhatEnc, err := cl.Reencrypt(*roster, oid, auth) + require.NoError(t, err) + secretRec, err := DecodeKey(cothority.Suite, X, C, XhatEnc, kp.Private) + require.NoError(t, err) + require.Equal(t, secret, secretRec) + } +} diff --git a/ocs/cli/cli.go b/ocs/cli/cli.go new file mode 100644 index 0000000000..071d0de28c --- /dev/null +++ b/ocs/cli/cli.go @@ -0,0 +1,73 @@ +package main + +import ( + "bytes" + "os" + + "go.dedis.ch/cothority/v3" + "go.dedis.ch/cothority/v3/byzcoin/bcadmin/lib" + "go.dedis.ch/cothority/v3/ocs" + "go.dedis.ch/kyber/v3/util/key" + "go.dedis.ch/onet/v3/log" +) + +func main() { + if len(os.Args) != 2 { + log.Fatal("Please give a roster.toml as first parameter") + } + roster, err := lib.ReadRoster(os.Args[1]) + log.ErrFatal(err) + + log.Info("Creating local certs") + caPrivKey, caCert, err := ocs.CreateCaCert() + log.ErrFatal(err) + log.Lvl5(caPrivKey) + + px := ocs.Policy{ + X509Cert: &ocs.PolicyX509Cert{ + CA: [][]byte{caCert.Raw}, + Threshold: 1, + }, + } + + log.Info("Creating new OCS") + cl := ocs.NewClient() + var oid ocs.OCSID + for i := 0; i < 10; i++ { + oid, err = cl.CreateOCS(*roster, px, px) + log.ErrFatal(err) + } + log.Infof("New OCS created with ID: %x", oid) + + log.Info("Creating secret key and encrypting it with the OCS-key") + secret := []byte("ocs for everybody") + X, err := oid.X() + log.ErrFatal(err) + U, C, err := ocs.EncodeKey(cothority.Suite, X, secret) + log.ErrFatal(err) + + log.Info("Creating certificate for the re-encryption") + kp := key.NewKeyPair(cothority.Suite) + wid, err := ocs.NewWriteID(X, U) + log.ErrFatal(err) + reencryptCert, err := ocs.CreateReencryptCert(caCert, caPrivKey, wid, kp.Public) + log.ErrFatal(err) + auth := ocs.AuthReencrypt{ + Ephemeral: kp.Public, + X509Cert: &ocs.AuthReencryptX509Cert{ + U: U, + Certificates: [][]byte{reencryptCert.Raw}, + }, + } + + log.Info("Asking OCS to re-encrypt the secret to an ephemeral key") + XhatEnc, err := cl.Reencrypt(*roster, oid, auth) + log.ErrFatal(err) + secretRec, err := ocs.DecodeKey(cothority.Suite, X, C, XhatEnc, kp.Private) + log.ErrFatal(err) + if bytes.Compare(secret, secretRec) != 0 { + log.Fatal("Recovered secret is not the same") + } + + log.Info("Successfully re-encrypted the key") +} diff --git a/ocs/helper.go b/ocs/helper.go new file mode 100644 index 0000000000..b9535815a0 --- /dev/null +++ b/ocs/helper.go @@ -0,0 +1,97 @@ +package ocs + +import ( + "errors" + "fmt" + "runtime" + "strings" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/suites" + "go.dedis.ch/onet/v3/log" +) + +// EncodeKey can be used by the writer to an onchain-secret skipchain +// to encode his symmetric key under the collective public key created +// by the DKG. +// As this method uses `Pick` to encode the key, depending on the key-length +// more than one point is needed to encode the data. +// +// Input: +// - suite - the cryptographic suite to use +// - X - the aggregate public key of the DKG +// - key - the symmetric key for the document +// +// Output: +// - U - the schnorr commit +// - C - encrypted key +func EncodeKey(suite suites.Suite, X kyber.Point, key []byte) (U kyber.Point, C kyber.Point, err error) { + if len(key) > suite.Point().EmbedLen() { + return nil, nil, errors.New("got more data than can fit into one point") + } + r := suite.Scalar().Pick(suite.RandomStream()) + C = suite.Point().Mul(r, X) + log.Lvl3("C:", C.String()) + U = suite.Point().Mul(r, nil) + log.Lvl3("U is:", U.String()) + + kp := suite.Point().Embed(key, suite.RandomStream()) + log.Lvl3("Keypoint:", kp.String()) + log.Lvl3("X:", X.String()) + C.Add(C, kp) + return +} + +// DecodeKey can be used by the reader of an onchain-secret to convert the +// re-encrypted secret back to a symmetric key that can be used later to +// decode the document. +// +// Input: +// - suite - the cryptographic suite to use +// - X - the aggregate public key of the DKG +// - C - the encrypted key +// - XhatEnc - the re-encrypted schnorr-commit +// - xc - the private key of the reader +// +// Output: +// - key - the re-assembled key +// - err - an eventual error when trying to recover the data from the points +func DecodeKey(suite kyber.Group, X kyber.Point, C kyber.Point, XhatEnc kyber.Point, + xc kyber.Scalar) (key []byte, err error) { + log.Lvl3("xc:", xc) + xcInv := suite.Scalar().Neg(xc) + log.Lvl3("xcInv:", xcInv) + sum := suite.Scalar().Add(xc, xcInv) + log.Lvl3("xc + xcInv:", sum, "::", xc) + log.Lvl3("X:", X) + XhatDec := suite.Point().Mul(xcInv, X) + log.Lvl3("XhatDec:", XhatDec) + log.Lvl3("XhatEnc:", XhatEnc) + Xhat := suite.Point().Add(XhatEnc, XhatDec) + log.Lvl3("Xhat:", Xhat) + XhatInv := suite.Point().Neg(Xhat) + log.Lvl3("XhatInv:", XhatInv) + + // Decrypt C to keyPointHat + log.Lvl3("C:", C) + keyPointHat := suite.Point().Add(C, XhatInv) + log.Lvl3("keyPointHat:", keyPointHat) + key, err = keyPointHat.Data() + if err != nil { + return nil, Erret(err) + } + log.Lvl3("key:", key) + return +} + +func Erret(err error) error { + if err == nil { + return nil + } + pc, _, line, _ := runtime.Caller(1) + errStr := err.Error() + if strings.HasPrefix(errStr, "Erret") { + errStr = "\n\t" + errStr + } + return fmt.Errorf("Erret at %s: %d -> %s", runtime.FuncForPC(pc).Name(), line, errStr) +} diff --git a/ocs/proto.go b/ocs/proto.go index 9e1b0d5c67..23c0a807e6 100644 --- a/ocs/proto.go +++ b/ocs/proto.go @@ -45,8 +45,19 @@ type CreateOCS struct { // is the collective signature of all nodes on the aggregate public key // and the authentication. type CreateOCSReply struct { - X OCSID - Sig []byte + OcsID OCSID +} + +// GetProof is sent to a node to have him sign his definition of the +// given OCS. +type GetProof struct { + OcsID OCSID +} + +// GetProofReply contains the additional info that node has on the given +// OCS, as well as a signature using the services private key. +type GetProofReply struct { + Proof OCSProof } // Reencrypt is sent to the service to request a re-encryption of the @@ -54,8 +65,8 @@ type CreateOCSReply struct { // request is valid, as well as the ephemeral key, to which the secret // will be re-encrypted. type Reencrypt struct { - X OCSID - Auth AuthReencrypt + OcsID OCSID + Auth AuthReencrypt } // MessageReencryptReply is the reply if the re-encryption is successful, and @@ -73,7 +84,7 @@ type ReencryptReply struct { // TODO: should NewRoster be always present in AuthReshare? It will be present // TODO: at least in AuthReshareByzCoin, but might not in other AuthReshares type Reshare struct { - X OCSID + OcsID OCSID NewRoster onet.Roster Auth AuthReshare } @@ -172,3 +183,12 @@ type AuthReshareByzCoin struct { type AuthReshareX509Cert struct { Certificates [][]byte } + +// OCSProof can be used to proof +type OCSProof struct { + OcsID OCSID + Roster onet.Roster + PolicyReencrypt Policy + PolicyReshare Policy + Signatures [][]byte +} diff --git a/ocs/protocol.go b/ocs/protocol.go index 4775083b80..c417930829 100644 --- a/ocs/protocol.go +++ b/ocs/protocol.go @@ -157,10 +157,11 @@ func (o *OCS) reencryptReply(rr structReencryptReply) error { if len(o.replies) >= int(o.Threshold-1) { o.Uis = make([]*share.PubShare, len(o.List())) var err error - o.Uis[0], err = o.getUI(o.U, o.Xc) + ui, err := o.getUI(o.U, o.Xc) if err != nil { return err } + o.Uis[ui.I] = ui for _, r := range o.replies { // Verify proofs diff --git a/ocs/protocol_test.go b/ocs/protocol_test.go index ee346b2a76..9df2f9a8d9 100644 --- a/ocs/protocol_test.go +++ b/ocs/protocol_test.go @@ -368,79 +368,6 @@ func (s *testService) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericC } } -// EncodeKey can be used by the writer to an onchain-secret skipchain -// to encode his symmetric key under the collective public key created -// by the DKG. -// As this method uses `Pick` to encode the key, depending on the key-length -// more than one point is needed to encode the data. -// -// Input: -// - suite - the cryptographic suite to use -// - X - the aggregate public key of the DKG -// - key - the symmetric key for the document -// -// Output: -// - U - the schnorr commit -// - C - encrypted key -func EncodeKey(suite suites.Suite, X kyber.Point, key []byte) (U kyber.Point, C kyber.Point, err error) { - if len(key) > suite.Point().EmbedLen() { - return nil, nil, errors.New("got more data than can fit into one point") - } - r := suite.Scalar().Pick(suite.RandomStream()) - C = suite.Point().Mul(r, X) - log.Lvl3("C:", C.String()) - U = suite.Point().Mul(r, nil) - log.Lvl3("U is:", U.String()) - - kp := suite.Point().Embed(key, suite.RandomStream()) - log.Lvl3("Keypoint:", kp.String()) - log.Lvl3("X:", X.String()) - C.Add(C, kp) - return -} - -// DecodeKey can be used by the reader of an onchain-secret to convert the -// re-encrypted secret back to a symmetric key that can be used later to -// decode the document. -// -// Input: -// - suite - the cryptographic suite to use -// - X - the aggregate public key of the DKG -// - C - the encrypted key -// - XhatEnc - the re-encrypted schnorr-commit -// - xc - the private key of the reader -// -// Output: -// - key - the re-assembled key -// - err - an eventual error when trying to recover the data from the points -func DecodeKey(suite kyber.Group, X kyber.Point, C kyber.Point, XhatEnc kyber.Point, - xc kyber.Scalar) (key []byte, err error) { - log.Lvl3("xc:", xc) - xcInv := suite.Scalar().Neg(xc) - log.Lvl3("xcInv:", xcInv) - sum := suite.Scalar().Add(xc, xcInv) - log.Lvl3("xc + xcInv:", sum, "::", xc) - log.Lvl3("X:", X) - XhatDec := suite.Point().Mul(xcInv, X) - log.Lvl3("XhatDec:", XhatDec) - log.Lvl3("XhatEnc:", XhatEnc) - Xhat := suite.Point().Add(XhatEnc, XhatDec) - log.Lvl3("Xhat:", Xhat) - XhatInv := suite.Point().Neg(Xhat) - log.Lvl3("XhatInv:", XhatInv) - - // Decrypt C to keyPointHat - log.Lvl3("C:", C) - keyPointHat := suite.Point().Add(C, XhatInv) - log.Lvl3("keyPointHat:", keyPointHat) - key, err = keyPointHat.Data() - if err != nil { - return nil, erret(err) - } - log.Lvl3("key:", key) - return -} - // starts a new service. No function needed. func newTestService(c *onet.Context) (onet.Service, error) { s := &testService{ diff --git a/ocs/service.go b/ocs/service.go index dffbed9ce6..d24fdf5636 100644 --- a/ocs/service.go +++ b/ocs/service.go @@ -12,6 +12,10 @@ import ( "os" "time" + "go.dedis.ch/kyber/v3/sign/schnorr" + + "go.dedis.ch/kyber/v3/suites" + "go.dedis.ch/cothority/v3" dkgprotocol "go.dedis.ch/cothority/v3/dkg/pedersen" "go.dedis.ch/kyber/v3" @@ -41,7 +45,7 @@ func init() { var err error _, err = onet.GlobalProtocolRegister(calypsoReshareProto, dkgprotocol.NewSetup) log.ErrFatal(err) - OCSServiceID, err = onet.RegisterNewService(ServiceName, newService) + OCSServiceID, err = onet.RegisterNewServiceWithSuite(ServiceName, suites.MustFind("ed25519"), newService) log.ErrFatal(err) network.RegisterMessages(&storage{}, &storageElement{}) @@ -91,18 +95,17 @@ func (s *Service) ProcessClientRequest(req *http.Request, path string, buf []byt // decryption requests. func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { if err = req.verify(); err != nil { - return nil, erret(err) + return nil, Erret(err) } - // NOTE: the roster stored in ByzCoin must have myself. tree := req.Roster.GenerateNaryTreeWithRoot(len(req.Roster.List), s.ServerIdentity()) cfgBuf, err := protobuf.Encode(req) if err != nil { - return nil, erret(err) + return nil, Erret(err) } pi, err := s.CreateProtocol(dkgprotocol.Name, tree) if err != nil { - return nil, erret(err) + return nil, Erret(err) } setupDKG := pi.(*dkgprotocol.Setup) setupDKG.Wait = true @@ -110,24 +113,27 @@ func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { setupDKG.KeyPair = s.getKeyPair() if err := pi.Start(); err != nil { - return nil, erret(err) + return nil, Erret(err) } log.Lvl3("Started DKG-protocol - waiting for done", len(req.Roster.List)) + var oid []byte select { case <-setupDKG.Finished: shared, dks, err := setupDKG.SharedSecret() if err != nil { - return nil, erret(err) + return nil, Erret(err) + } + ocsID, err := NewOCSID(shared.X) + if err != nil { + return nil, Erret(err) } reply = &CreateOCSReply{ - X: shared.X, - // TODO: calculate signature - Sig: []byte{}, + OcsID: ocsID, } - oid, err := shared.X.MarshalBinary() + oid, err = shared.X.MarshalBinary() if err != nil { - return nil, erret(err) + return nil, Erret(err) } s.storage.Lock() s.storage.Element[string(oid)] = &storageElement{ @@ -147,6 +153,34 @@ func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { return } +// GetProof returns a signed proof of the requested OcsID. +func (s *Service) GetProof(req *GetProof) (reply *GetProofReply, err error) { + s.storage.Lock() + es, found := s.storage.Element[string(req.OcsID)] + if !found { + return nil, errors.New("didn't find the given OCS") + } + s.storage.Unlock() + reply = &GetProofReply{ + Proof: OCSProof{ + OcsID: req.OcsID, + Roster: es.Roster, + PolicyReencrypt: es.PolicyReencrypt, + PolicyReshare: es.PolicyReshare, + }, + } + msg, err := reply.Proof.Message() + if err != nil { + return nil, Erret(err) + } + sig, err := schnorr.Sign(cothority.Suite, s.ServerIdentity().ServicePrivate(ServiceName), msg) + if err != nil { + return nil, Erret(err) + } + reply.Proof.Signatures = [][]byte{sig} + return +} + // Reencrypt takes as an input a Read- and a Write-proof. Proofs contain // everything necessary to verify that a given instance is correct and // stored in ByzCoin. @@ -158,12 +192,7 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { log.Lvl2(s.ServerIdentity(), "Re-encrypt the key to the public key of the reader") s.storage.Lock() - id, err := dkr.X.MarshalBinary() - if err != nil { - s.storage.Unlock() - return nil, erret(err) - } - es, found := s.storage.Element[string(id)] + es, found := s.storage.Element[string(dkr.OcsID)] s.storage.Unlock() if !found { return nil, errors.New("didn't find this OCS") @@ -179,20 +208,23 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { tree := es.Roster.GenerateNaryTreeWithRoot(nodes, s.ServerIdentity()) pi, err := s.CreateProtocol(NameOCS, tree) if err != nil { - return erret(err) + return Erret(err) } - log.Print("Created OCS", pi.Token().ID()) ocsProto = pi.(*OCS) ocsProto.U, err = dkr.Auth.U() if err != nil { - return erret(err) + return Erret(err) + } + X, err := dkr.OcsID.X() + if err != nil { + return Erret(err) } - if err = dkr.Auth.verify(es.PolicyReencrypt, dkr.X, ocsProto.U); err != nil { - return erret(err) + if err = dkr.Auth.verify(es.PolicyReencrypt, X, ocsProto.U); err != nil { + return Erret(err) } ocsProto.Xc, err = dkr.Auth.Xc() if err != nil { - return erret(err) + return Erret(err) } log.Lvlf2("%v Public key is: %s", s.ServerIdentity(), ocsProto.Xc) ocsProto.VerificationData, err = protobuf.Encode(&dkr.Auth) @@ -219,28 +251,28 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { return nil, err } - log.LLvl3("Starting reencryption protocol", ocsProto.TreeNodeInstance.TokenID()) - err = ocsProto.SetConfig(&onet.GenericConfig{Data: []byte(id)}) + log.Lvl3("Starting reencryption protocol", ocsProto.TreeNodeInstance.TokenID()) + err = ocsProto.SetConfig(&onet.GenericConfig{Data: dkr.OcsID}) if err != nil { - return nil, erret(err) + return nil, Erret(err) } err = ocsProto.Start() if err != nil { - return nil, erret(err) + return nil, Erret(err) } if !<-ocsProto.Reencrypted { return nil, errors.New("reencryption got refused") } - log.LLvl3("Reencryption protocol is done.") + log.Lvl3("Reencryption protocol is done.") reply.XhatEnc, err = share.RecoverCommit(cothority.Suite, ocsProto.Uis, threshold, nodes) if err != nil { - return nil, erret(err) + return nil, Erret(err) } if err != nil { - return nil, erret(err) + return nil, Erret(err) } - log.LLvl3("Successfully reencrypted the key") + log.Lvl3("Successfully reencrypted the key") return } @@ -362,7 +394,7 @@ func (s *Service) getKeyPair() *key.Pair { // NewProtocol intercepts the DKG and OCS protocols to retrieve the values func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfig) (onet.ProtocolInstance, error) { - log.LLvl3(s.ServerIdentity(), tn.ProtocolName(), len(conf.Data), tn.TokenID()) + log.Lvl3(s.ServerIdentity(), tn.ProtocolName(), len(conf.Data), tn.TokenID()) switch tn.ProtocolName() { case dkgprotocol.Name: var cfg CreateOCS @@ -399,6 +431,7 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi PolicyReencrypt: cfg.PolicyReencrypt, PolicyReshare: cfg.PolicyReshare, Shared: *shared, + Polys: pubPoly{s.Suite().Point().Base(), dks.Commits}, Roster: *tn.Roster(), DKS: *dks, } @@ -426,11 +459,7 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi setupDKG.KeyPair = s.getKeyPair() s.storage.Lock() - idBuf, err := cfg.X.MarshalBinary() - if err != nil { - return nil, err - } - id := string(idBuf) + id := string(cfg.OcsID) es, found := s.storage.Element[id] if !found { // TODO: we might not have this yet - so probably we need to put the old roster in cfg, too. @@ -500,7 +529,10 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi es.DKS = *dks s.storage.Unlock() - s.save() + err = s.save() + if err != nil { + log.Error("Couldn't save storage") + } if s.afterReshare != nil { s.afterReshare() } @@ -546,11 +578,11 @@ func (s *Service) verifyReencryption(rc *MessageReencrypt) bool { var arc AuthReencrypt err := protobuf.DecodeWithConstructors(*rc.VerificationData, &arc, network.DefaultConstructors(cothority.Suite)) if err != nil { - return erret(err) + return Erret(err) } Xc, err := arc.Xc() if err != nil { - return erret(err) + return Erret(err) } if !Xc.Equal(rc.Xc) { return errors.New("Xcs don't match up") @@ -571,7 +603,8 @@ func newService(c *onet.Context) (onet.Service, error) { s := &Service{ ServiceProcessor: onet.NewServiceProcessor(c), } - if err := s.RegisterHandlers(s.CreateOCS, s.ReshareLTS, s.Reencrypt); err != nil { + if err := s.RegisterHandlers(s.CreateOCS, s.ReshareLTS, s.Reencrypt, + s.GetProof); err != nil { return nil, errors.New("couldn't register messages") } if err := s.tryLoad(); err != nil { diff --git a/ocs/service_test.go b/ocs/service_test.go index 53783964de..167d30d573 100644 --- a/ocs/service_test.go +++ b/ocs/service_test.go @@ -39,8 +39,7 @@ func TestService_CreateOCS(t *testing.T) { cor, err := s1.CreateOCS(co) require.NoError(t, err) require.NotNil(t, cor) - require.NotNil(t, cor.X) - require.NoError(t, co.CheckOCSSignature(cor.Sig, cor.X)) + require.NotNil(t, cor.OcsID) // Do the same with an invalid X509 px.X509Cert.CA = nil @@ -84,19 +83,20 @@ func TestService_Reencrypt(t *testing.T) { } cor, err := s1.CreateOCS(co) require.NoError(t, err) - require.NoError(t, co.CheckOCSSignature(cor.Sig, cor.X)) secret := []byte("ocs for all") - U, C, err := EncodeKey(cothority.Suite, cor.X, secret) + X, err := cor.OcsID.X() + require.NoError(t, err) + U, C, err := EncodeKey(cothority.Suite, X, secret) require.NoError(t, err) kp := key.NewKeyPair(cothority.Suite) - wid, err := NewWriteID(cor.X, U) + wid, err := NewWriteID(X, U) require.NoError(t, err) reencryptCert, err := CreateReencryptCert(caCertAttack, caPrivKeyAttack, wid, kp.Public) require.NoError(t, err) req := &Reencrypt{ - X: cor.X, + OcsID: cor.OcsID, Auth: AuthReencrypt{ Ephemeral: kp.Public, X509Cert: &AuthReencryptX509Cert{ @@ -114,7 +114,8 @@ func TestService_Reencrypt(t *testing.T) { rr, err = s1.Reencrypt(req) require.NoError(t, err) - secretRec, err := DecodeKey(cothority.Suite, cor.X, C, rr.XhatEnc, kp.Private) + require.NoError(t, err) + secretRec, err := DecodeKey(cothority.Suite, X, C, rr.XhatEnc, kp.Private) require.NoError(t, err) require.Equal(t, secret, secretRec) } diff --git a/ocs/struct.go b/ocs/struct.go index ace8216c2f..78740a240a 100644 --- a/ocs/struct.go +++ b/ocs/struct.go @@ -1,14 +1,9 @@ package ocs import ( - "bytes" "crypto/sha256" "crypto/x509" - "encoding/asn1" "errors" - "fmt" - "runtime" - "strings" "go.dedis.ch/cothority/v3" "go.dedis.ch/kyber/v3/sign/schnorr" @@ -29,20 +24,37 @@ func (ocs CreateOCS) verify() error { return nil } -func (ocs CreateOCS) CheckOCSSignature(sig []byte, X OCSID) error { - // TODO: test signature - return nil - if sig == nil { - return errors.New("no signature given") +func (op OCSProof) Verify() error { + if len(op.Signatures) != len(op.Roster.List) { + return errors.New("length of signatures is not equal to roster list length") + } + msg, err := op.Message() + if err != nil { + return Erret(err) } + for i, si := range op.Roster.List { + err := schnorr.Verify(cothority.Suite, si.ServicePublic(ServiceName), msg, op.Signatures[i]) + if err != nil { + return Erret(err) + } + } + return nil +} + +func (op OCSProof) Message() ([]byte, error) { hash := sha256.New() - X.MarshalTo(hash) - buf, err := protobuf.Encode(ocs) + hash.Write(op.OcsID) + coc := CreateOCS{ + Roster: op.Roster, + PolicyReencrypt: op.PolicyReencrypt, + PolicyReshare: op.PolicyReshare, + } + buf, err := protobuf.Encode(&coc) if err != nil { - return erret(err) + return nil, Erret(err) } hash.Write(buf) - return erret(schnorr.Verify(cothority.Suite, ocs.Roster.Aggregate, hash.Sum(nil), sig)) + return hash.Sum(nil), nil } func (re Reshare) verify() error { @@ -65,7 +77,7 @@ func (px PolicyX509Cert) verify(r onet.Roster) error { } func (px PolicyByzCoin) verify(r onet.Roster) error { - return erret(errors.New("net yet implemented")) + return Erret(errors.New("not yet implemented")) } func (ar AuthReencrypt) verify(p Policy, X, U kyber.Point) error { @@ -74,22 +86,18 @@ func (ar AuthReencrypt) verify(p Policy, X, U kyber.Point) error { } root, err := x509.ParseCertificate(p.X509Cert.CA[0]) if err != nil { - return erret(err) + return Erret(err) } auth, err := x509.ParseCertificate(ar.X509Cert.Certificates[0]) if err != nil { - return erret(err) - } - wid, err := getExtensionFromCert(auth, WriteIdOID) - if err != nil { - return erret(err) + return Erret(err) } - err = WriteID(wid).Verify(X, U) + + ocsID, err := NewOCSID(X) if err != nil { - return erret(err) + return Erret(err) } - - return erret(Verify(root, auth)) + return Erret(Verify(root, auth, ocsID, U)) } func (ar AuthReencrypt) Xc() (kyber.Point, error) { @@ -111,69 +119,3 @@ func (ar AuthReencrypt) U() (kyber.Point, error) { } return nil, errors.New("need to have authentication for X509 or ByzCoin") } - -type WriteID []byte - -func NewWriteID(X, U kyber.Point) (WriteID, error) { - wid := sha256.New() - _, err := X.MarshalTo(wid) - if err != nil { - return nil, erret(err) - } - _, err = U.MarshalTo(wid) - if err != nil { - return nil, erret(err) - } - return wid.Sum(nil), nil -} - -func (wid WriteID) Verify(X, U kyber.Point) error { - other, err := NewWriteID(X, U) - if err != nil { - return erret(err) - } - if bytes.Compare(wid, other) != 0 { - return errors.New("not the same writeID") - } - return nil -} - -func getPointFromCert(certBuf []byte, extID asn1.ObjectIdentifier) (kyber.Point, error) { - cert, err := x509.ParseCertificate(certBuf) - if err != nil { - return nil, erret(err) - } - secret := cothority.Suite.Point() - secretBuf, err := getExtensionFromCert(cert, extID) - if err != nil { - return nil, erret(err) - } - err = secret.UnmarshalBinary(secretBuf) - return secret, erret(err) -} - -func getExtensionFromCert(cert *x509.Certificate, extID asn1.ObjectIdentifier) ([]byte, error) { - var buf []byte - for _, ext := range cert.Extensions { - if ext.Id.Equal(extID) { - buf = ext.Value - break - } - } - if buf == nil { - return nil, errors.New("didn't find extension in certificate") - } - return buf, nil -} - -func erret(err error) error { - if err == nil { - return nil - } - pc, _, line, _ := runtime.Caller(1) - errStr := err.Error() - if strings.HasPrefix(errStr, "erret") { - errStr = "\n\t" + errStr - } - return fmt.Errorf("erret at %s: %d -> %s", runtime.FuncForPC(pc).Name(), line, errStr) -} diff --git a/ocs/verify.go b/ocs/verify.go index d1401eb31a..fd00c48565 100644 --- a/ocs/verify.go +++ b/ocs/verify.go @@ -1,9 +1,20 @@ package ocs import ( + "bytes" + "crypto/sha256" "crypto/x509" "crypto/x509/pkix" "encoding/asn1" + "errors" + + "go.dedis.ch/cothority/v3/calypso" + "go.dedis.ch/kyber/v3/sign/schnorr" + "go.dedis.ch/onet/v3" + "go.dedis.ch/protobuf" + + "go.dedis.ch/cothority/v3" + "go.dedis.ch/kyber/v3" ) var ( @@ -14,24 +25,127 @@ var ( EphemeralKeyOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 2} ) -func Verify(rootCert *x509.Certificate, toVerify *x509.Certificate) (err error) { +// Verify takes a root certificate and the certificate to verify. It then verifies +// the certificates with regard to the signature of the root-certificate to the +// authCert. +// ocsID is the ID of the LTS cothority, while U is the commitment to the secret. +func Verify(rootCert *x509.Certificate, authCert *x509.Certificate, ocsID OCSID, U kyber.Point) (err error) { roots := x509.NewCertPool() roots.AddCert(rootCert) - cert, err := x509.ParseCertificate(toVerify.Raw) + cert, err := x509.ParseCertificate(authCert.Raw) if err != nil { - return erret(err) + return Erret(err) } opts := x509.VerifyOptions{ Roots: roots, } + wid, err := getExtensionFromCert(authCert, WriteIdOID) + if err != nil { + return Erret(err) + } + X, err := ocsID.X() + if err != nil { + return Erret(err) + } + err = WriteID(wid).Verify(X, U) + if err != nil { + return Erret(err) + } + unmarkUnhandledCriticalExtension(cert, WriteIdOID) unmarkUnhandledCriticalExtension(cert, EphemeralKeyOID) _, err = cert.Verify(opts) - return erret(err) + return Erret(err) +} + +// WriteID is the ID that will be revealed to the +type WriteID []byte + +func NewWriteID(X, U kyber.Point) (WriteID, error) { + wid := sha256.New() + _, err := X.MarshalTo(wid) + if err != nil { + return nil, Erret(err) + } + _, err = U.MarshalTo(wid) + if err != nil { + return nil, Erret(err) + } + return wid.Sum(nil), nil +} + +func (wid WriteID) Verify(X, U kyber.Point) error { + other, err := NewWriteID(X, U) + if err != nil { + return Erret(err) + } + if bytes.Compare(wid, other) != 0 { + return errors.New("not the same writeID") + } + return nil +} + +func NewOCSID(X kyber.Point) (OCSID, error) { + return X.MarshalBinary() +} + +func (ocs OCSID) X() (kyber.Point, error) { + X := cothority.Suite.Point() + err := Erret(X.UnmarshalBinary(ocs)) + return X, err +} + +func (ocs OCSID) Verify(roster onet.Roster, policyReencrypt, policyReshare Policy, sig []byte) error { + return Erret(errors.New("use CreateOCS.CheckOCSSignature")) + msg := sha256.New() + msg.Write(ocs) + policyBuf, err := protobuf.Encode(policyReencrypt) + if err != nil { + return Erret(err) + } + msg.Write(policyBuf) + policyBuf, err = protobuf.Encode(policyReencrypt) + if err != nil { + return Erret(err) + } + msg.Write(policyBuf) + agg, err := roster.ServiceAggregate(calypso.ServiceName) + if err != nil { + return Erret(err) + } + return Erret(schnorr.Verify(cothority.Suite, agg, msg.Sum(nil), sig)) +} + +func getPointFromCert(certBuf []byte, extID asn1.ObjectIdentifier) (kyber.Point, error) { + cert, err := x509.ParseCertificate(certBuf) + if err != nil { + return nil, Erret(err) + } + secret := cothority.Suite.Point() + secretBuf, err := getExtensionFromCert(cert, extID) + if err != nil { + return nil, Erret(err) + } + err = secret.UnmarshalBinary(secretBuf) + return secret, Erret(err) +} + +func getExtensionFromCert(cert *x509.Certificate, extID asn1.ObjectIdentifier) ([]byte, error) { + var buf []byte + for _, ext := range cert.Extensions { + if ext.Id.Equal(extID) { + buf = ext.Value + break + } + } + if buf == nil { + return nil, errors.New("didn't find extension in certificate") + } + return buf, nil } func unmarkUnhandledCriticalExtension(cert *x509.Certificate, id asn1.ObjectIdentifier) { diff --git a/ocs/verify_test.go b/ocs/verify_test.go deleted file mode 100644 index 92dc849773..0000000000 --- a/ocs/verify_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package ocs - -import ( - "crypto/x509" - "encoding/pem" - "errors" - "testing" - - "github.com/stretchr/testify/require" -) - -const ( - rootCert1 = `-----BEGIN CERTIFICATE----- -MIIB1jCCATigAwIBAgIBATAKBggqhkjOPQQDBDAdMRswGQYDVQQDExJCeXpHZW4g -c2lnbmVyIG9yZzEwHhcNMTkwMzI4MjEwNzUxWhcNNDQwMzIxMjEwNzUxWjAdMRsw -GQYDVQQDExJCeXpHZW4gc2lnbmVyIG9yZzEwgZswEAYHKoZIzj0CAQYFK4EEACMD -gYYABABqdo+aDVte5Fz/xG5Z2GYmIbcVJdXxrMJrTBYgHQafSw0BBKrAyeMcZ534 -/V6eNfkiZa3kuflo6Y2E/NtVxyl7dgFBYTdqvLtPdg7+K7pdj8eKFrAQ0DDi5S0x -aM96oR3S0bU4MIbfMqW1fAsLPw3476Gvju73bfJhEJ3ukx6W2olq+KMmMCQwDgYD -VR0PAQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYIKoZIzj0EAwQDgYsA -MIGHAkEcvPgm0qnXMgpJiOD52VUL3qTwU6uzRYhwIWa3sWCP471/muzsq6PctAEu -CHkpnAlH3DuS2MBBql8ifwwK2PdOGQJCAQcE3+qdiyrABJ315INCTu6HAjpGv0cR -VQWcCmSs80tS9gzvQJ8+peWRuzGvy1Uoyj0qHTSJOHx6z86oOIVbXAIj ------END CERTIFICATE-----` - - validPem = `-----BEGIN CERTIFICATE----- -MIICKTCCAYqgAwIBAgIQYNsgS2KrQ1ptA7E+cRfiUjAKBggqhkjOPQQDBDAdMRsw -GQYDVQQDExJCeXpHZW4gc2lnbmVyIG9yZzEwHhcNMTkwMzI4MjEwNzUxWhcNMTkw -NDExMjEwNzUxWjAoMSYwJAYDVQQDDB1FcGhlbWVyYWwgcmVhZCBvcGVyYXRpb24g -JiBDbzB2MBAGByqGSM49AgEGBSuBBAAiA2IABPEbevkxsAu3BqZjMBzl+ppSLX1F -4oqnAUxmXx+Yw9mgyunTWzHKPAgHoYmaVDL2a+MDVngmbJI+BiXaZBE00gW854pz -ROa1Z7KxjYGgbRINavXX5nSTbs+xH3w76d3ppKOBgzCBgDAOBgNVHQ8BAf8EBAMC -BSAwDAYDVR0TAQH/BAIwADAvBggrBgEFBQcNAQEB/wQg7PBd8YGomyUmjZpqOy9h -gdAdKEfArphKLRkkozsRRvIwLwYIKwYBBQUHDQIBAf8EIBuJzdwW5DfOVymjPvBM -YXsz+apB9URZnhN1jZy2wrixMAoGCCqGSM49BAMEA4GMADCBiAJCAYwxRrOwCydO -r5KoAndH8/U9nIaM4BWcx1pwYFMM44P0BzXDQgDSYwIAhAQ5hvOpaMPB4IMKI37C -G1lsOKivZEboAkIA90UbyVD7ahZdbpCDKUYAoVejKgA5JAsm8kUGPWt+siw2hsT9 -V/NTETY3evBjoX8kkWs/E5pWpwEGKPQaS25gw1s= ------END CERTIFICATE-----` -) - -func Test_VerifyCertificateHappyDayScenario(t *testing.T) { - caCert, _ := certFromPem([]byte(rootCert1)) - cert, _ := certFromPem([]byte(validPem)) - - require.NoError(t, Verify(caCert, cert)) -} - -func certFromPem(pemCerts []byte) (cert *x509.Certificate, err error) { - var block *pem.Block - - block, pemCerts = pem.Decode(pemCerts) - - if block.Type != "CERTIFICATE" { - return nil, errors.New("expected a certificate") - } - - return x509.ParseCertificate(block.Bytes) -} diff --git a/ocs/x509_test.go b/ocs/x509.go similarity index 82% rename from ocs/x509_test.go rename to ocs/x509.go index 4d4e3cb774..d5f23f85c3 100644 --- a/ocs/x509_test.go +++ b/ocs/x509.go @@ -12,10 +12,7 @@ import ( "go.dedis.ch/kyber/v3" ) -// openssl ecparam -name secp384r1 -genkey -noout -outform der -out secp384r1-key.der -// openssl pkcs8 -topk8 -nocrypt -outform der -inform der -in secp384r1-key.der -out secp384r1-pkcs8.der -// openssl ec -inform der -in secp384r1-key.der -pubout -outform der -out secp384r1-pub.der - +// CreateCaCert is used for tests and returns a new private key, as well as a CA certificate. func CreateCaCert() (caPrivKey *ecdsa.PrivateKey, cert *x509.Certificate, err error) { notBefore := time.Now() notAfter := notBefore.Add(25 * 365 * 24 * time.Hour) @@ -36,20 +33,21 @@ func CreateCaCert() (caPrivKey *ecdsa.PrivateKey, cert *x509.Certificate, err er } caPrivKey, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) if err != nil { - return nil, nil, erret(err) + return nil, nil, Erret(err) } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &caPrivKey.PublicKey, caPrivKey) if err != nil { - return nil, nil, erret(err) + return nil, nil, Erret(err) } cert, err = x509.ParseCertificate(derBytes) if err != nil { - return nil, nil, erret(err) + return nil, nil, Erret(err) } return } +// CreateReencryptCert is used for tests and can create a certificate for one of the nodes. func CreateReencryptCert(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, writeID []byte, ephemeralPublicKey kyber.Point) (*x509.Certificate, error) { @@ -59,7 +57,7 @@ func CreateReencryptCert(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { - return nil, erret(err) + return nil, Erret(err) } writeIdExt := pkix.Extension{ @@ -70,7 +68,7 @@ func CreateReencryptCert(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, ephBuf, err := ephemeralPublicKey.MarshalBinary() if err != nil { - return nil, erret(err) + return nil, Erret(err) } ephemeralKeyExt := pkix.Extension{ Id: EphemeralKeyOID, @@ -95,16 +93,16 @@ func CreateReencryptCert(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, throwaway, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) if err != nil { - return nil, erret(err) + return nil, Erret(err) } derBytes, err := x509.CreateCertificate(rand.Reader, &template, caCert, &throwaway.PublicKey, caPrivKey) if err != nil { - return nil, erret(err) + return nil, Erret(err) } cert, err := x509.ParseCertificate(derBytes) if err != nil { - return nil, erret(err) + return nil, Erret(err) } return cert, nil From eada6c1d49800cbb023052e73d7de166f4682db0 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Fri, 12 Apr 2019 17:06:33 +0200 Subject: [PATCH 11/21] removing local onet --- go.mod | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.mod b/go.mod index 6dce3bc51b..c5b91663f2 100644 --- a/go.mod +++ b/go.mod @@ -22,5 +22,3 @@ require ( gopkg.in/square/go-jose.v2 v2.2.2 // indirect gopkg.in/urfave/cli.v1 v1.20.0 ) - -replace go.dedis.ch/onet/v3 => ../onet From 2592640a4d3533472eab0e5ba68292062bdd72e3 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Mon, 15 Apr 2019 11:18:44 +0200 Subject: [PATCH 12/21] adding root-CA and cleaning up --- go.sum | 1 + ocs/api.go | 6 ++++ ocs/api_test.go | 6 ++-- ocs/cli/cli.go | 50 +++++++++++++++++++---------- ocs/db.go | 3 +- ocs/{ => libtest}/helper.go | 2 +- ocs/{ => libtest}/x509.go | 64 +++++++++++++++++++++++++++++++++---- ocs/proto.go | 31 ++++++++++++++++++ ocs/service.go | 38 +++++++++++++++------- ocs/service_test.go | 8 ++--- ocs/struct.go | 18 ++++++----- ocs/verify.go | 36 +++++++++++---------- 12 files changed, 195 insertions(+), 68 deletions(-) rename ocs/{ => libtest}/helper.go (99%) rename ocs/{ => libtest}/x509.go (56%) diff --git a/go.sum b/go.sum index fac228b8a0..21489750ec 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,7 @@ go.dedis.ch/kyber/v3 v3.0.2 h1:dhYLJksmOau7TYf1JS0iTpW6Bus+mtqxJBbM0Q/E9HU= go.dedis.ch/kyber/v3 v3.0.2/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= go.dedis.ch/onet/v3 v3.0.2 h1:+jBLnoQBHMDJ1lVgkcbmkKNWqXma8n9R/5/7VZ1wZls= go.dedis.ch/onet/v3 v3.0.2/go.mod h1:xqmP2+NvxeNzgmNj/4hf56EZm3KT0Qksz98miZw5G3A= +go.dedis.ch/onet/v3 v3.0.5 h1:Ysm96KuRt1OavrRpa1Vi09DqljXBCDwaiur34DTvra8= go.dedis.ch/onet/v3 v3.0.5/go.mod h1:0wrof0zfyD+Qfw9Pfhu9jW+bTbwwWBzC1hMuV/c8v2w= go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo= go.dedis.ch/protobuf v1.0.6 h1:E61p2XjYbYrTf3WeXE8M8Ui5WA3hX/NgbHHi5D0FLxI= diff --git a/ocs/api.go b/ocs/api.go index c928e97963..e9f3a28d81 100644 --- a/ocs/api.go +++ b/ocs/api.go @@ -4,6 +4,7 @@ import ( "go.dedis.ch/cothority/v3" "go.dedis.ch/kyber/v3" "go.dedis.ch/onet/v3" + "go.dedis.ch/onet/v3/network" ) // TODO: think about authentication @@ -21,6 +22,11 @@ func NewClient() *Client { return &Client{Client: onet.NewClient(cothority.Suite, ServiceName)} } +// AddPolicyCreateOCS stores who is allowed to create new OCS instances. +func (c *Client) AddPolicyCreateOCS(si *network.ServerIdentity, policy Policy) error { + return c.SendProtobuf(si, &AddPolicyCreateOCS{Create: policy}, nil) +} + // CreateOCS starts a new Distributed Key Generation with the nodes in the roster and // returns the collective public key X. This X is also used later to identify the // LTS instance, as there can be more than one LTS group on a node. diff --git a/ocs/api_test.go b/ocs/api_test.go index 05b96547dd..93d5b56853 100644 --- a/ocs/api_test.go +++ b/ocs/api_test.go @@ -19,7 +19,7 @@ func TestClient_GetProofs(t *testing.T) { nbrNodes := 5 _, roster, _ := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) - _, caCert, err := CreateCaCert() + _, caCert, err := CreateCertCa() require.NoError(t, err) px := Policy{ @@ -45,7 +45,7 @@ func TestClient_Reencrypt(t *testing.T) { nbrNodes := 5 _, roster, _ := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) - caPrivKey, caCert, err := CreateCaCert() + caPrivKey, caCert, err := CreateCertCa() require.NoError(t, err) log.Lvl5(caPrivKey) @@ -72,7 +72,7 @@ func TestClient_Reencrypt(t *testing.T) { kp := key.NewKeyPair(cothority.Suite) wid, err := NewWriteID(X, U) require.NoError(t, err) - reencryptCert, err := CreateReencryptCert(caCert, caPrivKey, wid, kp.Public) + reencryptCert, err := CreateCertReencrypt(caCert, caPrivKey, wid, kp.Public) require.NoError(t, err) auth := AuthReencrypt{ Ephemeral: kp.Public, diff --git a/ocs/cli/cli.go b/ocs/cli/cli.go index 071d0de28c..a3fc80aee9 100644 --- a/ocs/cli/cli.go +++ b/ocs/cli/cli.go @@ -1,9 +1,17 @@ +// Demo of how the new OCS service works from an outside, non-go-test caller. It does the following steps: +// 1. set up a root CA that is stored in the service as being allowed to create new OCS-instances +// 2. Create a new OCS-instance with a reencryption policy being set by a node-certificate +// 3. Encrypt a symmetric key to the OCS-instance public key +// 4. Ask the OCS-instance to re-encrypt the key to an ephemeral key +// 5. Decrypt the symmetric key package main import ( "bytes" "os" + "go.dedis.ch/cothority/v3/ocs/libtest" + "go.dedis.ch/cothority/v3" "go.dedis.ch/cothority/v3/byzcoin/bcadmin/lib" "go.dedis.ch/cothority/v3/ocs" @@ -18,39 +26,45 @@ func main() { roster, err := lib.ReadRoster(os.Args[1]) log.ErrFatal(err) - log.Info("Creating local certs") - caPrivKey, caCert, err := ocs.CreateCaCert() + log.Info("1. Creating createOCS cert and setting OCS-create policy") + cl := ocs.NewClient() + coPrivKey, coCert, err := libtest.CreateCertCa() + log.ErrFatal(err) + for _, si := range roster.List { + err = cl.AddPolicyCreateOCS(si, ocs.Policy{X509Cert: &ocs.PolicyX509Cert{ + CA: [][]byte{coCert.Raw}, + }}) + log.ErrFatal(err) + } + + log.Info("2.a) Creating node cert") + nodePrivKey, nodeCert, err := libtest.CreateCertNode(coCert, coPrivKey) log.ErrFatal(err) - log.Lvl5(caPrivKey) px := ocs.Policy{ X509Cert: &ocs.PolicyX509Cert{ - CA: [][]byte{caCert.Raw}, + CA: [][]byte{nodeCert.Raw}, Threshold: 1, }, } - log.Info("Creating new OCS") - cl := ocs.NewClient() - var oid ocs.OCSID - for i := 0; i < 10; i++ { - oid, err = cl.CreateOCS(*roster, px, px) - log.ErrFatal(err) - } + log.Info("2.b) Creating new OCS") + oid, err := cl.CreateOCS(*roster, px, px) + log.ErrFatal(err) log.Infof("New OCS created with ID: %x", oid) - log.Info("Creating secret key and encrypting it with the OCS-key") + log.Info("3.a) Creating secret key and encrypting it with the OCS-key") secret := []byte("ocs for everybody") X, err := oid.X() log.ErrFatal(err) - U, C, err := ocs.EncodeKey(cothority.Suite, X, secret) + U, C, err := libtest.EncodeKey(cothority.Suite, X, secret) log.ErrFatal(err) - log.Info("Creating certificate for the re-encryption") + log.Info("3.b) Creating certificate for the re-encryption") kp := key.NewKeyPair(cothority.Suite) wid, err := ocs.NewWriteID(X, U) log.ErrFatal(err) - reencryptCert, err := ocs.CreateReencryptCert(caCert, caPrivKey, wid, kp.Public) + reencryptCert, err := libtest.CreateCertReencrypt(nodeCert, nodePrivKey, wid, kp.Public) log.ErrFatal(err) auth := ocs.AuthReencrypt{ Ephemeral: kp.Public, @@ -60,10 +74,12 @@ func main() { }, } - log.Info("Asking OCS to re-encrypt the secret to an ephemeral key") + log.Info("4. Asking OCS to re-encrypt the secret to an ephemeral key") XhatEnc, err := cl.Reencrypt(*roster, oid, auth) log.ErrFatal(err) - secretRec, err := ocs.DecodeKey(cothority.Suite, X, C, XhatEnc, kp.Private) + + log.Info("5. Decrypt the symmetric key") + secretRec, err := libtest.DecodeKey(cothority.Suite, X, C, XhatEnc, kp.Private) log.ErrFatal(err) if bytes.Compare(secret, secretRec) != 0 { log.Fatal("Recovered secret is not the same") diff --git a/ocs/db.go b/ocs/db.go index 0a0ba7d3ac..6a74597edd 100644 --- a/ocs/db.go +++ b/ocs/db.go @@ -18,7 +18,8 @@ var storageKey = []byte("storage") // storage is used to save all elements of the DKG. type storage struct { - Element map[string]*storageElement + Element map[string]*storageElement + PolicyCreateOCS []Policy sync.Mutex } diff --git a/ocs/helper.go b/ocs/libtest/helper.go similarity index 99% rename from ocs/helper.go rename to ocs/libtest/helper.go index b9535815a0..c0b415496a 100644 --- a/ocs/helper.go +++ b/ocs/libtest/helper.go @@ -1,4 +1,4 @@ -package ocs +package libtest import ( "errors" diff --git a/ocs/x509.go b/ocs/libtest/x509.go similarity index 56% rename from ocs/x509.go rename to ocs/libtest/x509.go index d5f23f85c3..1cf16ae179 100644 --- a/ocs/x509.go +++ b/ocs/libtest/x509.go @@ -1,4 +1,4 @@ -package ocs +package libtest import ( "crypto/ecdsa" @@ -12,8 +12,15 @@ import ( "go.dedis.ch/kyber/v3" ) -// CreateCaCert is used for tests and returns a new private key, as well as a CA certificate. -func CreateCaCert() (caPrivKey *ecdsa.PrivateKey, cert *x509.Certificate, err error) { +// Helper functions to create x509-certificates. They are supposed to be used in the following +// way: +// +// CertCa - is the basic certificate that can create CertNodes +// +-> CertNode - can be given as a CA for Reencryption and Resharing +// +-> CertReencrypt - indicates who is allowed to reencrypt and gives the ephemeral key + +// CreateCertCa is used for tests and returns a new private key, as well as a CA certificate. +func CreateCertCa() (caPrivKey *ecdsa.PrivateKey, cert *x509.Certificate, err error) { notBefore := time.Now() notAfter := notBefore.Add(25 * 365 * 24 * time.Hour) serialNumber := big.NewInt(1) @@ -28,7 +35,7 @@ func CreateCaCert() (caPrivKey *ecdsa.PrivateKey, cert *x509.Certificate, err er KeyUsage: x509.KeyUsageCertSign, BasicConstraintsValid: true, - MaxPathLen: 1, + MaxPathLen: 2, IsCA: true, } caPrivKey, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) @@ -47,8 +54,53 @@ func CreateCaCert() (caPrivKey *ecdsa.PrivateKey, cert *x509.Certificate, err er return } -// CreateReencryptCert is used for tests and can create a certificate for one of the nodes. -func CreateReencryptCert(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, +// CreateCertNode is used for tests and can create a certificate for one of the nodes. +func CreateCertNode(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey) ( + nodePrivKey *ecdsa.PrivateKey, nodeCert *x509.Certificate, err error) { + + notBefore := time.Now() + // 10 years for a node certificate + notAfter := notBefore.Add(31e6 * 10 * time.Second) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + return nil, nil, Erret(err) + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + CommonName: "Node certificate", + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: x509.KeyUsageCertSign, + MaxPathLen: 1, + BasicConstraintsValid: true, + IsCA: true, + } + + nodePrivKey, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) + if err != nil { + return nil, nil, Erret(err) + } + derBytes, err := x509.CreateCertificate(rand.Reader, &template, caCert, &nodePrivKey.PublicKey, caPrivKey) + if err != nil { + return nil, nil, Erret(err) + } + + nodeCert, err = x509.ParseCertificate(derBytes) + if err != nil { + return nil, nil, Erret(err) + } + + return +} + +// CreateCertReencrypt is used for tests and can create a certificate for a reencryption request. +func CreateCertReencrypt(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, writeID []byte, ephemeralPublicKey kyber.Point) (*x509.Certificate, error) { notBefore := time.Now() diff --git a/ocs/proto.go b/ocs/proto.go index 23c0a807e6..0f9c5fc567 100644 --- a/ocs/proto.go +++ b/ocs/proto.go @@ -26,6 +26,17 @@ import ( // API calls // *** +// AddPolicyCreateOCS is sent by a local admin to add a rule to define who is +// authorized to create a new OCS. +type AddPolicyCreateOCS struct { + Create Policy +} + +// AddPolicyCreateOCSReply is an empty reply if the policy has been successfully +// created. +type AddPolicyCreateOCSReply struct { +} + // CreateOCS is sent to the service to request a new OCS cothority. // It holds the two policies necessary to define an OCS: how to // authenticate a reencryption request, and how to authenticate a @@ -127,6 +138,26 @@ type PolicyX509Cert struct { Threshold int } +// AuthCreate prooves that the caller has the right to create a new OCS +// instance. +type AuthCreate struct { + ByzCoin AuthCreateByzcoin + X509Cert AuthCreateX509Cert +} + +// AuthCreateByzcoin must give the ByzcoinID and the proof to the LTSInstance +// for the creation of a new OCS. +type AuthCreateByzcoin struct { + ByzcoinID skipchain.SkipBlockID + LTSInstance byzcoin.Proof +} + +// AuthCreateX509Cert must give a threshold number of certificates to proof that +// the caller has the right to create a new OCS. +type AuthCreateX509Cert struct { + Certificates [][]byte +} + // AuthReencrypt holds one of the possible authentication proofs for a reencryption request. Each // authentication proof must hold the secret to be reencrypted, the ephemeral key, as well // as the proof itself that the request is valid. For each of the authentication diff --git a/ocs/service.go b/ocs/service.go index d24fdf5636..f5822860ce 100644 --- a/ocs/service.go +++ b/ocs/service.go @@ -28,9 +28,6 @@ import ( "go.dedis.ch/protobuf" ) -// Used for tests -var OCSServiceID onet.ServiceID - // ServiceName of the secret-management part of Calypso. const ServiceName = "OCS" @@ -45,7 +42,7 @@ func init() { var err error _, err = onet.GlobalProtocolRegister(calypsoReshareProto, dkgprotocol.NewSetup) log.ErrFatal(err) - OCSServiceID, err = onet.RegisterNewServiceWithSuite(ServiceName, suites.MustFind("ed25519"), newService) + _, err = onet.RegisterNewServiceWithSuite(ServiceName, suites.MustFind("ed25519"), newService) log.ErrFatal(err) network.RegisterMessages(&storage{}, &storageElement{}) @@ -72,10 +69,10 @@ type pubPoly struct { } // ProcessClientRequest implements onet.Service. We override the version -// we normally get from embeddeding onet.ServiceProcessor in order to +// we normally get from embedding onet.ServiceProcessor in order to // hook it and get a look at the http.Request. func (s *Service) ProcessClientRequest(req *http.Request, path string, buf []byte) ([]byte, *onet.StreamingTunnel, error) { - if !disableLoopbackCheck && path == "CreateOCS" { + if !disableLoopbackCheck && path == "AddPolicyCreateOCS" { h, _, err := net.SplitHostPort(req.RemoteAddr) if err != nil { return nil, nil, err @@ -90,6 +87,16 @@ func (s *Service) ProcessClientRequest(req *http.Request, path string, buf []byt return s.ServiceProcessor.ProcessClientRequest(req, path, buf) } +// AddPolicyCreateOCS defines who is allowed to create new OCS instances. Per default +// it only accepts requests on the localhost interface. But this can be overridden +// by the COTHORITY_ALLOW_INSECURE_ADMIN variable. +func (s *Service) AddPolicyCreateOCS(req *AddPolicyCreateOCS) (reply *AddPolicyCreateOCSReply, err error) { + s.storage.Lock() + s.storage.PolicyCreateOCS = append(s.storage.PolicyCreateOCS, req.Create) + s.storage.Unlock() + return &AddPolicyCreateOCSReply{}, s.save() +} + // CreateOCS takes as input a roster with a list of all nodes that should // participate in the DKG. Every node will store its private key and wait for // decryption requests. @@ -109,7 +116,10 @@ func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { } setupDKG := pi.(*dkgprotocol.Setup) setupDKG.Wait = true - setupDKG.SetConfig(&onet.GenericConfig{Data: cfgBuf}) + err = setupDKG.SetConfig(&onet.GenericConfig{Data: cfgBuf}) + if err != nil { + return nil, Erret(err) + } setupDKG.KeyPair = s.getKeyPair() if err := pi.Start(); err != nil { @@ -145,7 +155,10 @@ func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { DKS: *dks, } s.storage.Unlock() - s.save() + err = s.save() + if err != nil { + return nil, err + } log.Lvlf2("%v Created LTS with ID (=^pubKey): %x", s.ServerIdentity(), oid) case <-time.After(propagationTimeout): return nil, errors.New("new-dkg didn't finish in time") @@ -436,7 +449,10 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi DKS: *dks, } s.storage.Unlock() - s.save() + err = s.save() + if err != nil { + log.Error(err) + } }() return pi, nil @@ -585,7 +601,7 @@ func (s *Service) verifyReencryption(rc *MessageReencrypt) bool { return Erret(err) } if !Xc.Equal(rc.Xc) { - return errors.New("Xcs don't match up") + return errors.New("xcs don't match up") } return nil }() @@ -604,7 +620,7 @@ func newService(c *onet.Context) (onet.Service, error) { ServiceProcessor: onet.NewServiceProcessor(c), } if err := s.RegisterHandlers(s.CreateOCS, s.ReshareLTS, s.Reencrypt, - s.GetProof); err != nil { + s.GetProof, s.AddPolicyCreateOCS); err != nil { return nil, errors.New("couldn't register messages") } if err := s.tryLoad(); err != nil { diff --git a/ocs/service_test.go b/ocs/service_test.go index 167d30d573..4327c3530e 100644 --- a/ocs/service_test.go +++ b/ocs/service_test.go @@ -65,9 +65,9 @@ func TestService_Reencrypt(t *testing.T) { // Test setting up a new OCS with a valid X509 s1 := servers[0].Service(ServiceName).(*Service) - caPrivKey, caCert, err := CreateCaCert() + caPrivKey, caCert, err := CreateCertCa() require.NoError(t, err) - caPrivKeyAttack, caCertAttack, err := CreateCaCert() + caPrivKeyAttack, caCertAttack, err := CreateCertCa() require.NoError(t, err) px := Policy{ @@ -93,7 +93,7 @@ func TestService_Reencrypt(t *testing.T) { kp := key.NewKeyPair(cothority.Suite) wid, err := NewWriteID(X, U) require.NoError(t, err) - reencryptCert, err := CreateReencryptCert(caCertAttack, caPrivKeyAttack, wid, kp.Public) + reencryptCert, err := CreateCertReencrypt(caCertAttack, caPrivKeyAttack, wid, kp.Public) require.NoError(t, err) req := &Reencrypt{ OcsID: cor.OcsID, @@ -108,7 +108,7 @@ func TestService_Reencrypt(t *testing.T) { rr, err := s1.Reencrypt(req) require.Error(t, err) - reencryptCert, err = CreateReencryptCert(caCert, caPrivKey, wid, kp.Public) + reencryptCert, err = CreateCertReencrypt(caCert, caPrivKey, wid, kp.Public) require.NoError(t, err) req.Auth.X509Cert.Certificates = [][]byte{reencryptCert.Raw} rr, err = s1.Reencrypt(req) diff --git a/ocs/struct.go b/ocs/struct.go index 78740a240a..9c39954c8c 100644 --- a/ocs/struct.go +++ b/ocs/struct.go @@ -5,6 +5,8 @@ import ( "crypto/x509" "errors" + "go.dedis.ch/cothority/v3/ocs/libtest" + "go.dedis.ch/cothority/v3" "go.dedis.ch/kyber/v3/sign/schnorr" "go.dedis.ch/protobuf" @@ -30,12 +32,12 @@ func (op OCSProof) Verify() error { } msg, err := op.Message() if err != nil { - return Erret(err) + return libtest.Erret(err) } for i, si := range op.Roster.List { err := schnorr.Verify(cothority.Suite, si.ServicePublic(ServiceName), msg, op.Signatures[i]) if err != nil { - return Erret(err) + return libtest.Erret(err) } } return nil @@ -51,7 +53,7 @@ func (op OCSProof) Message() ([]byte, error) { } buf, err := protobuf.Encode(&coc) if err != nil { - return nil, Erret(err) + return nil, libtest.Erret(err) } hash.Write(buf) return hash.Sum(nil), nil @@ -77,7 +79,7 @@ func (px PolicyX509Cert) verify(r onet.Roster) error { } func (px PolicyByzCoin) verify(r onet.Roster) error { - return Erret(errors.New("not yet implemented")) + return libtest.Erret(errors.New("not yet implemented")) } func (ar AuthReencrypt) verify(p Policy, X, U kyber.Point) error { @@ -86,18 +88,18 @@ func (ar AuthReencrypt) verify(p Policy, X, U kyber.Point) error { } root, err := x509.ParseCertificate(p.X509Cert.CA[0]) if err != nil { - return Erret(err) + return libtest.Erret(err) } auth, err := x509.ParseCertificate(ar.X509Cert.Certificates[0]) if err != nil { - return Erret(err) + return libtest.Erret(err) } ocsID, err := NewOCSID(X) if err != nil { - return Erret(err) + return libtest.Erret(err) } - return Erret(Verify(root, auth, ocsID, U)) + return libtest.Erret(Verify(root, auth, ocsID, U)) } func (ar AuthReencrypt) Xc() (kyber.Point, error) { diff --git a/ocs/verify.go b/ocs/verify.go index fd00c48565..8da5178fb9 100644 --- a/ocs/verify.go +++ b/ocs/verify.go @@ -8,6 +8,8 @@ import ( "encoding/asn1" "errors" + "go.dedis.ch/cothority/v3/ocs/libtest" + "go.dedis.ch/cothority/v3/calypso" "go.dedis.ch/kyber/v3/sign/schnorr" "go.dedis.ch/onet/v3" @@ -35,7 +37,7 @@ func Verify(rootCert *x509.Certificate, authCert *x509.Certificate, ocsID OCSID, cert, err := x509.ParseCertificate(authCert.Raw) if err != nil { - return Erret(err) + return libtest.Erret(err) } opts := x509.VerifyOptions{ @@ -44,22 +46,22 @@ func Verify(rootCert *x509.Certificate, authCert *x509.Certificate, ocsID OCSID, wid, err := getExtensionFromCert(authCert, WriteIdOID) if err != nil { - return Erret(err) + return libtest.Erret(err) } X, err := ocsID.X() if err != nil { - return Erret(err) + return libtest.Erret(err) } err = WriteID(wid).Verify(X, U) if err != nil { - return Erret(err) + return libtest.Erret(err) } unmarkUnhandledCriticalExtension(cert, WriteIdOID) unmarkUnhandledCriticalExtension(cert, EphemeralKeyOID) _, err = cert.Verify(opts) - return Erret(err) + return libtest.Erret(err) } // WriteID is the ID that will be revealed to the @@ -69,11 +71,11 @@ func NewWriteID(X, U kyber.Point) (WriteID, error) { wid := sha256.New() _, err := X.MarshalTo(wid) if err != nil { - return nil, Erret(err) + return nil, libtest.Erret(err) } _, err = U.MarshalTo(wid) if err != nil { - return nil, Erret(err) + return nil, libtest.Erret(err) } return wid.Sum(nil), nil } @@ -81,7 +83,7 @@ func NewWriteID(X, U kyber.Point) (WriteID, error) { func (wid WriteID) Verify(X, U kyber.Point) error { other, err := NewWriteID(X, U) if err != nil { - return Erret(err) + return libtest.Erret(err) } if bytes.Compare(wid, other) != 0 { return errors.New("not the same writeID") @@ -95,43 +97,43 @@ func NewOCSID(X kyber.Point) (OCSID, error) { func (ocs OCSID) X() (kyber.Point, error) { X := cothority.Suite.Point() - err := Erret(X.UnmarshalBinary(ocs)) + err := libtest.Erret(X.UnmarshalBinary(ocs)) return X, err } func (ocs OCSID) Verify(roster onet.Roster, policyReencrypt, policyReshare Policy, sig []byte) error { - return Erret(errors.New("use CreateOCS.CheckOCSSignature")) + return libtest.Erret(errors.New("use CreateOCS.CheckOCSSignature")) msg := sha256.New() msg.Write(ocs) policyBuf, err := protobuf.Encode(policyReencrypt) if err != nil { - return Erret(err) + return libtest.Erret(err) } msg.Write(policyBuf) policyBuf, err = protobuf.Encode(policyReencrypt) if err != nil { - return Erret(err) + return libtest.Erret(err) } msg.Write(policyBuf) agg, err := roster.ServiceAggregate(calypso.ServiceName) if err != nil { - return Erret(err) + return libtest.Erret(err) } - return Erret(schnorr.Verify(cothority.Suite, agg, msg.Sum(nil), sig)) + return libtest.Erret(schnorr.Verify(cothority.Suite, agg, msg.Sum(nil), sig)) } func getPointFromCert(certBuf []byte, extID asn1.ObjectIdentifier) (kyber.Point, error) { cert, err := x509.ParseCertificate(certBuf) if err != nil { - return nil, Erret(err) + return nil, libtest.Erret(err) } secret := cothority.Suite.Point() secretBuf, err := getExtensionFromCert(cert, extID) if err != nil { - return nil, Erret(err) + return nil, libtest.Erret(err) } err = secret.UnmarshalBinary(secretBuf) - return secret, Erret(err) + return secret, libtest.Erret(err) } func getExtensionFromCert(cert *x509.Certificate, extID asn1.ObjectIdentifier) ([]byte, error) { From fe6c8c08d369a889b9218e9b6c5b10a851ca6e7e Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Mon, 15 Apr 2019 13:26:51 +0200 Subject: [PATCH 13/21] updating READMEs --- conode/Dockerfile-dev | 2 +- ocs/OCS.md | 51 ---------- ocs/README.md | 168 +++++++++++++++++-------------- ocs/api.go | 3 +- ocs/{libtest => certs}/helper.go | 2 +- ocs/{ => certs}/verify.go | 78 ++++---------- ocs/{libtest => certs}/x509.go | 2 +- ocs/demo/README.md | 35 +++++++ ocs/{cli/cli.go => demo/main.go} | 23 +++-- ocs/service.go | 44 ++++---- ocs/struct.go | 32 +++--- 11 files changed, 208 insertions(+), 232 deletions(-) delete mode 100644 ocs/OCS.md rename ocs/{libtest => certs}/helper.go (99%) rename ocs/{ => certs}/verify.go (58%) rename ocs/{libtest => certs}/x509.go (99%) create mode 100644 ocs/demo/README.md rename ocs/{cli/cli.go => demo/main.go} (75%) diff --git a/conode/Dockerfile-dev b/conode/Dockerfile-dev index fbcb4b603d..16c8434e72 100644 --- a/conode/Dockerfile-dev +++ b/conode/Dockerfile-dev @@ -10,4 +10,4 @@ COPY exe/conode.Linux.x86_64 ./conode EXPOSE 7770 7771 -CMD "./run_nodes.sh -n 1" +CMD ["./run_nodes.sh", "-n 1", "-v 2", "-d /conode_data"] diff --git a/ocs/OCS.md b/ocs/OCS.md deleted file mode 100644 index 9f4db7a37f..0000000000 --- a/ocs/OCS.md +++ /dev/null @@ -1,51 +0,0 @@ -Navigation: [DEDIS](https://github.com/dedis/doc/tree/master/README.md) :: -[Cothority](../README.md) :: -[Applications](../doc/Applications.md) :: -[Onchain Secrets](README.md) :: -Protocols - -# Protocols - -The onet-framework uses protocols at its lowest level to define communication -patterns betwen nodes. We use two protocols in the onchain-secrets service: - -- [DKG](../dkg/DKG.md) - Distributed Key Generation, an implementation of - the following paper: "Secure Distributed Key Generation for Discrete-Log - Based Cryptosystems" by R. Gennaro, S. Jarecki, H. Krawczyk, and T. Rabin. -- [ocs](Renecrypt.md) - the long-term secrets version of the on-chain secrets - protocol with server-side secret reconstruction described in - [CALYPSO](https://eprint.iacr.org/2018/209.pdf). - -## Distributed Key Generation - -The DKG protocol creates random shares of a secret key that are only -stored at each node. Together these nodes create a public shared key -without creating the secret shared key. As a group they can encrypt -and decrypt data without the need to create the secret shared key, -but with each node participating in part of the encryption or -decryption. For more information, please see [here](../dkg/DKG.md). - -## Onchain-Secrets - -Based on the DKG, data that is ElGamal encrypted using the public -shared key from the DKG can be re-encrypted under another public key -without the data being in the clear at any given moment. This is used -in the onchain-secrets skipchain when a reader wants to recover the -symmetric key. - -# Variables used - -When going through the code, the variables follow the CALYPSO paper -in the Appendix B under **Secret reconstruction at the trusted server** -as far as possible. - -Here is a short recap of the different variable-names used in the -re-encryption: - -- X: the aggregate public key of the OCS (LTS), also used as the -ID of the OCS -- C: the ElGamal part of the data, with maximal key-length of 240 bits for -Ed25519 -- U: the encrypted random value for the ElGamal encryption -- Xc: the public key of the reader under which U will be re-encrypted -- XHatEnc: the re-encrypted random value for the ElGamal encryption \ No newline at end of file diff --git a/ocs/README.md b/ocs/README.md index ae4e441a95..8c8e6dc8e3 100644 --- a/ocs/README.md +++ b/ocs/README.md @@ -1,104 +1,122 @@ Navigation: [DEDIS](https://github.com/dedis/doc/tree/master/README.md) :: [Cothority](../README.md) :: [Applications](../doc/Applications.md) :: -Calypso +Onchain-Secrets -# Calypso +# Onchain-Secrets (OCS) -Calypso is the implementation of the upcoming "Calypso - Auditable Sharing of -Private Data over Blockchains". The paper can be found +Calypso is a system to store secrets in plain sight, for example in a blockchain. +It is composed in two parts, as described in the paper at [here](https://eprint.iacr.org/2018/209). +![Workflow Overview](CalypsoByzCoin.png?raw=true "Workflow Overview") -In short, Calypso allows to store symmetric keys in ByzCoin, protected by a -sharded key, and controls access to this symmetric keys using Darcs, -Distributed Access Rights Control. - -It implements both the access-control cothority and the secret-management -cothority: -- The access-control cothority is implemented using ByzCoin with two - contracts, `calypsoWrite` and `calypsoRead` -- The secret-management cothority uses an onet service with methods to set up a - Long Term Secret (LTS) distributed key and to request a re-encryption - -The workflow is the following: -1. secret-management: Administrator sets up a new LTS for all his clients. It - does so by calling the `CreateLTS` service endpoint. The resulting `LTSID` - will be used by all clients. -2. access-control: Administrator gives document creation rights to a writer -3. access-control: Writer creates new Darcs for customers and for documents. -4. access-control: Writer spawns a `Write` instance from a document Darc -5. access-control: Reader requests that a `Read` instance is spawned from a - `Write` instance -6. secret-management: Reader requests a re-encryption to the `DecryptKey` - service endpoint. +1. Access Control Cothority - implemented using Byzcoin in [Calypso](../calypso/README.md) +2. Secret Management Cothority - implemented in this directory -![Workflow Overview](CalypsoByzCoin.png?raw=true "Workflow Overview") +There is a simple demo the functionality of the system: +[OCS Demo](demo/README.md) + +# Protocols + +The onet-framework uses protocols at its lowest level to define communication +patterns betwen nodes. We use two protocols in the onchain-secrets service: + +- [DKG](../dkg/DKG.md) - Distributed Key Generation, an implementation of + the following paper: "Secure Distributed Key Generation for Discrete-Log + Based Cryptosystems" by R. Gennaro, S. Jarecki, H. Krawczyk, and T. Rabin. +- [ocs](Renecrypt.md) - the long-term secrets version of the on-chain secrets + protocol with server-side secret reconstruction described in + [CALYPSO](https://eprint.iacr.org/2018/209.pdf). + +## Distributed Key Generation + +The DKG protocol creates random shares of a secret key that are only +stored at each node. Together these nodes create a public shared key +without creating the secret shared key. As a group they can encrypt +and decrypt data without the need to create the secret shared key, +but with each node participating in part of the encryption or +decryption. For more information, please see [here](../dkg/DKG.md). + +## Onchain-Secrets -## Darcs, Instances, Instructions and Contracts +Based on the DKG, data that is ElGamal encrypted using the public +shared key from the DKG can be re-encrypted under another public key +without the data being in the clear at any given moment. This is used +in the onchain-secrets skipchain when a reader wants to recover the +symmetric key. -Here is a very short overview of the three most important elements of -ByzCoin. For a more thorough documentation, refer to -[ByzCoin](../byzcoin/README.md) documentation. +# Variables used -The current ByzCoin service is a batching implementation of the previous -skipchain service. It has a global state that holds _Instances_, where every -instance is tied to a _Contract_ and holds a blob of data. The contract defines -how the data is to be interpreted and allows different _Instructions_ sent from -the user. +When going through the code, the variables follow the CALYPSO paper +in the Appendix B under **Secret reconstruction at the trusted server** +as far as possible. -Access control is done using _Darcs_, which define what public keys can verify -an action. Each instruction received by ByzCoin is mapped to an action and -then verified if the given signature is correct. Also, every instance is linked -to one darc that defines what actions are allowed to be done to that instance. +Here is a short recap of the different variable-names used in the +re-encryption: -All instructions sent to ByzCoin are batched in a new block that is created -every `blockInterval` seconds. +- X: the aggregate public key of the OCS (LTS), also used as the +ID of the OCS +- C: the ElGamal part of the data, with maximal key-length of 240 bits for +Ed25519 +- U: the encrypted random value for the ElGamal encryption +- Xc: the public key of the reader under which U will be re-encrypted +- XHatEnc: the re-encrypted random value for the ElGamal encryption -## CreateLTS +# API -The CreateLTS endpoint is only usable when connecting to the conode -via localhost. It is possible to relax this restriction, but it should -only be done in testing environments; see `service.go`'s `init()` function -for how. +This onet-service offers an API to interact with the OnChain-Secrets service +and allows you to: -The client that initiates `CreateLTS` should hold two rosters. One roster for -storing the secret shares of LTS (long term secret), the other for a ByzCoin -instance for storing the LTS roster (using the LTS contract). +- `AddPolicyCreateOCS` - define who is allowed to create new OCS-instances +- `CreateOCS` - start a new OCS instance +- `GetProofs` - returns a list of signatures from nodes on an OCS-instance +- `Reencrypt` - request a reencryption on an encrypted secret +- `Reshare` - not implemented - re-define the set of nodes holding an OCS-instance -If the LTS roster does not exist on ByzCoin, the client is responsible for -creating it. Which can be done by sending a ByzCoin transaction. The -transaction should spawn a new LTS instance. +For all the policies and authentications, different Access Control Cothorities +can be defined. Currently the two following ACCs are defined: -After the LTS roster is on ByzCoin but before the creation of LTS shares. The -client should make a `CreateLTS` request to a node in the LTS roster. The -request should contain the instance ID that contains the LTS roster. Then, -every Calypso node should check that the instance ID that holds the LTS roster -exists before starting the DKG. For this operation, all nodes must be online. -By default, a threshold of 2/3 of the nodes must be present for the -decryption. +- `ByzCoin` - using DARCs to define access control +- `X509Cert` - using x509-certs to define who is allowed to access the system -The CreateLTS service endpoint returns a `LTSID` in the form of a 32 byte +## AddPolicyCreateOCS + +This is the entry point to the OCS system. Every node needs to define under +which policy he accepts new OCS instances. For the two ACCs, this is +defined as follows: + +- `ByzCoin` - by giving a byzcoin-ID, CreateOCS will accept every proof of +an LTSInstance that can be verified using a stored byzcoin-ID +- `X509Cert` - by giving a root-CA, CreateOCS will accept every request with +policies signed by this root-CA + +## CreateOCS + +Using the CreateOCS endpoint, a client can request the system to set up a +new OCS instance. The request is only accepted if the policy of one of the +ACCs is fulfilled: + +- `ByzCoin` - the proof given in the `Reencrypt` policy must be verifiable +with one of the stored byzcoin-IDs +- `X509Cert` - the certificate given in `Reencrypt` and `Reshare` must have +been signed by one of the root-CAs + +The CreateOCS service endpoint returns a `LTSID` in the form of a 32 byte slice. This ID represents the group that created the distributed key. Any node can participate in as many DKGs as you want and will get a random `LTSID` assigned. -## Write Contract - -The write contract verifies that the request has been correctly created, so -that no malicious writer can send an encrypted key without knowing the secret. -It then creates a new write-instance that contains the write request. - -A read request must also be sent to the write contract, which will forward it -to the read contract. This is so that every instruction sent to ByzCoin has -as a target an existing instance. +## GetProofs -## Read Contract +Once an OCS instance has been created, this API endpoint can be called. The +contacted node will send a request to sign the OCS-identity to all other nodes +and then return a list of all signatures, one per node. -The read contract verifies that the request is valid and points to the write -instance. It stores the reader's public key in the instance, so that the -secret-management cothority can re-encrypt to this reader's public key. +These signatures can be verified to make sure that the OCS-instance has been +correctly set up and that the node contacted in `CreateOCS` didn't change +the roster. -## Resharing LTS +## Reshare - not yet implemented It is possible that the roster might change and the LTS shares must be re-distributed but without changing the LTS itself. We accomplish this in two diff --git a/ocs/api.go b/ocs/api.go index e9f3a28d81..80e8543be4 100644 --- a/ocs/api.go +++ b/ocs/api.go @@ -2,6 +2,7 @@ package ocs import ( "go.dedis.ch/cothority/v3" + "go.dedis.ch/cothority/v3/ocs/certs" "go.dedis.ch/kyber/v3" "go.dedis.ch/onet/v3" "go.dedis.ch/onet/v3/network" @@ -61,7 +62,7 @@ func (c *Client) GetProofs(roster onet.Roster, OcsID OCSID) (op OCSProof, err er var reply GetProofReply err = c.SendProtobuf(si, &GetProof{OcsID}, &reply) if err != nil { - err = Erret(err) + err = certs.Erret(err) return } if len(op.Signatures) == 0 { diff --git a/ocs/libtest/helper.go b/ocs/certs/helper.go similarity index 99% rename from ocs/libtest/helper.go rename to ocs/certs/helper.go index c0b415496a..528dc0ad15 100644 --- a/ocs/libtest/helper.go +++ b/ocs/certs/helper.go @@ -1,4 +1,4 @@ -package libtest +package certs import ( "errors" diff --git a/ocs/verify.go b/ocs/certs/verify.go similarity index 58% rename from ocs/verify.go rename to ocs/certs/verify.go index 8da5178fb9..bb02c6c222 100644 --- a/ocs/verify.go +++ b/ocs/certs/verify.go @@ -1,4 +1,4 @@ -package ocs +package certs import ( "bytes" @@ -8,13 +8,6 @@ import ( "encoding/asn1" "errors" - "go.dedis.ch/cothority/v3/ocs/libtest" - - "go.dedis.ch/cothority/v3/calypso" - "go.dedis.ch/kyber/v3/sign/schnorr" - "go.dedis.ch/onet/v3" - "go.dedis.ch/protobuf" - "go.dedis.ch/cothority/v3" "go.dedis.ch/kyber/v3" ) @@ -31,51 +24,47 @@ var ( // the certificates with regard to the signature of the root-certificate to the // authCert. // ocsID is the ID of the LTS cothority, while U is the commitment to the secret. -func Verify(rootCert *x509.Certificate, authCert *x509.Certificate, ocsID OCSID, U kyber.Point) (err error) { +func Verify(rootCert *x509.Certificate, authCert *x509.Certificate, X kyber.Point, U kyber.Point) (err error) { roots := x509.NewCertPool() roots.AddCert(rootCert) cert, err := x509.ParseCertificate(authCert.Raw) if err != nil { - return libtest.Erret(err) + return Erret(err) } opts := x509.VerifyOptions{ Roots: roots, } - wid, err := getExtensionFromCert(authCert, WriteIdOID) + wid, err := GetExtensionFromCert(authCert, WriteIdOID) if err != nil { - return libtest.Erret(err) - } - X, err := ocsID.X() - if err != nil { - return libtest.Erret(err) + return Erret(err) } err = WriteID(wid).Verify(X, U) if err != nil { - return libtest.Erret(err) + return Erret(err) } unmarkUnhandledCriticalExtension(cert, WriteIdOID) unmarkUnhandledCriticalExtension(cert, EphemeralKeyOID) _, err = cert.Verify(opts) - return libtest.Erret(err) + return Erret(err) } -// WriteID is the ID that will be revealed to the +// WriteID is the ID that will be revealed to the X509 verification method. type WriteID []byte func NewWriteID(X, U kyber.Point) (WriteID, error) { wid := sha256.New() _, err := X.MarshalTo(wid) if err != nil { - return nil, libtest.Erret(err) + return nil, Erret(err) } _, err = U.MarshalTo(wid) if err != nil { - return nil, libtest.Erret(err) + return nil, Erret(err) } return wid.Sum(nil), nil } @@ -83,7 +72,7 @@ func NewWriteID(X, U kyber.Point) (WriteID, error) { func (wid WriteID) Verify(X, U kyber.Point) error { other, err := NewWriteID(X, U) if err != nil { - return libtest.Erret(err) + return Erret(err) } if bytes.Compare(wid, other) != 0 { return errors.New("not the same writeID") @@ -91,52 +80,21 @@ func (wid WriteID) Verify(X, U kyber.Point) error { return nil } -func NewOCSID(X kyber.Point) (OCSID, error) { - return X.MarshalBinary() -} - -func (ocs OCSID) X() (kyber.Point, error) { - X := cothority.Suite.Point() - err := libtest.Erret(X.UnmarshalBinary(ocs)) - return X, err -} - -func (ocs OCSID) Verify(roster onet.Roster, policyReencrypt, policyReshare Policy, sig []byte) error { - return libtest.Erret(errors.New("use CreateOCS.CheckOCSSignature")) - msg := sha256.New() - msg.Write(ocs) - policyBuf, err := protobuf.Encode(policyReencrypt) - if err != nil { - return libtest.Erret(err) - } - msg.Write(policyBuf) - policyBuf, err = protobuf.Encode(policyReencrypt) - if err != nil { - return libtest.Erret(err) - } - msg.Write(policyBuf) - agg, err := roster.ServiceAggregate(calypso.ServiceName) - if err != nil { - return libtest.Erret(err) - } - return libtest.Erret(schnorr.Verify(cothority.Suite, agg, msg.Sum(nil), sig)) -} - -func getPointFromCert(certBuf []byte, extID asn1.ObjectIdentifier) (kyber.Point, error) { +func GetPointFromCert(certBuf []byte, extID asn1.ObjectIdentifier) (kyber.Point, error) { cert, err := x509.ParseCertificate(certBuf) if err != nil { - return nil, libtest.Erret(err) + return nil, Erret(err) } secret := cothority.Suite.Point() - secretBuf, err := getExtensionFromCert(cert, extID) + secretBuf, err := GetExtensionFromCert(cert, extID) if err != nil { - return nil, libtest.Erret(err) + return nil, Erret(err) } err = secret.UnmarshalBinary(secretBuf) - return secret, libtest.Erret(err) + return secret, Erret(err) } -func getExtensionFromCert(cert *x509.Certificate, extID asn1.ObjectIdentifier) ([]byte, error) { +func GetExtensionFromCert(cert *x509.Certificate, extID asn1.ObjectIdentifier) ([]byte, error) { var buf []byte for _, ext := range cert.Extensions { if ext.Id.Equal(extID) { @@ -170,5 +128,3 @@ func getExtension(certificate *x509.Certificate, id asn1.ObjectIdentifier) *pkix return nil } - -// TODO: add CreateX509(rootCA, time, writeID, ephemeralKey) diff --git a/ocs/libtest/x509.go b/ocs/certs/x509.go similarity index 99% rename from ocs/libtest/x509.go rename to ocs/certs/x509.go index 1cf16ae179..36efc6c9c9 100644 --- a/ocs/libtest/x509.go +++ b/ocs/certs/x509.go @@ -1,4 +1,4 @@ -package libtest +package certs import ( "crypto/ecdsa" diff --git a/ocs/demo/README.md b/ocs/demo/README.md new file mode 100644 index 0000000000..99c2f7a9c0 --- /dev/null +++ b/ocs/demo/README.md @@ -0,0 +1,35 @@ +Navigation: [DEDIS](https://github.com/dedis/doc/tree/master/README.md) :: +[Cothority](../README.md) :: +[Applications](../doc/Applications.md) :: +[Onchain-Secrets](../README.md) :: +Demo + +# OCS Demo + +This demo does a simple run to show how to use the OCS with the X509 +certificates. To run it, you first need to run the docker image +to start 3 nodes locally: + +```bash +docker run -it -p 7770-7775:7770-7775 --rm -v$(pwd)/data:/conode_data -e COTHORITY_ALLOW_INSECURE_ADMIN=true c4dt/ocs:dev ./run_nodes.sh -n 3 -v 2 -c -d /conode_data +``` + +This creates 3 nodes that are listening on the localhost using the ports 7770-7775. +All data is stored in the `$(pwd)/data` directory. Once the nodes are up and running, +the demo can be started: + +```bash +cd cothority/ocs/demo +go run main.go +``` + +The demo will do the following: + +1. set up a root CA that is stored in the service as being allowed to create new OCS-instances +2. Create a new OCS-instance with a reencryption policy being set by a node-certificate +3. Encrypt a symmetric key to the OCS-instance public key +4. Ask the OCS-instance to re-encrypt the key to an ephemeral key +5. Decrypt the symmetric key + +All communication is done over the network, the same way as it has to be done in +a real system. diff --git a/ocs/cli/cli.go b/ocs/demo/main.go similarity index 75% rename from ocs/cli/cli.go rename to ocs/demo/main.go index a3fc80aee9..318d3b5505 100644 --- a/ocs/cli/cli.go +++ b/ocs/demo/main.go @@ -10,7 +10,7 @@ import ( "bytes" "os" - "go.dedis.ch/cothority/v3/ocs/libtest" + "go.dedis.ch/cothority/v3/ocs/certs" "go.dedis.ch/cothority/v3" "go.dedis.ch/cothority/v3/byzcoin/bcadmin/lib" @@ -28,7 +28,7 @@ func main() { log.Info("1. Creating createOCS cert and setting OCS-create policy") cl := ocs.NewClient() - coPrivKey, coCert, err := libtest.CreateCertCa() + coPrivKey, coCert, err := certs.CreateCertCa() log.ErrFatal(err) for _, si := range roster.List { err = cl.AddPolicyCreateOCS(si, ocs.Policy{X509Cert: &ocs.PolicyX509Cert{ @@ -38,7 +38,7 @@ func main() { } log.Info("2.a) Creating node cert") - nodePrivKey, nodeCert, err := libtest.CreateCertNode(coCert, coPrivKey) + nodePrivKey, nodeCert, err := certs.CreateCertNode(coCert, coPrivKey) log.ErrFatal(err) px := ocs.Policy{ @@ -53,18 +53,27 @@ func main() { log.ErrFatal(err) log.Infof("New OCS created with ID: %x", oid) + log.Info("2.c) Get proofs of all nodes") + proof, err := cl.GetProofs(*roster, oid) + log.ErrFatal(err) + log.ErrFatal(proof.Verify()) + log.Info("Proof got verified successfully on nodes:") + for i, sig := range proof.Signatures { + log.Infof("Signature %d of %s: %x", i, proof.Roster.List[i].Address, sig) + } + log.Info("3.a) Creating secret key and encrypting it with the OCS-key") secret := []byte("ocs for everybody") X, err := oid.X() log.ErrFatal(err) - U, C, err := libtest.EncodeKey(cothority.Suite, X, secret) + U, C, err := certs.EncodeKey(cothority.Suite, X, secret) log.ErrFatal(err) log.Info("3.b) Creating certificate for the re-encryption") kp := key.NewKeyPair(cothority.Suite) - wid, err := ocs.NewWriteID(X, U) + wid, err := certs.NewWriteID(X, U) log.ErrFatal(err) - reencryptCert, err := libtest.CreateCertReencrypt(nodeCert, nodePrivKey, wid, kp.Public) + reencryptCert, err := certs.CreateCertReencrypt(nodeCert, nodePrivKey, wid, kp.Public) log.ErrFatal(err) auth := ocs.AuthReencrypt{ Ephemeral: kp.Public, @@ -79,7 +88,7 @@ func main() { log.ErrFatal(err) log.Info("5. Decrypt the symmetric key") - secretRec, err := libtest.DecodeKey(cothority.Suite, X, C, XhatEnc, kp.Private) + secretRec, err := certs.DecodeKey(cothority.Suite, X, C, XhatEnc, kp.Private) log.ErrFatal(err) if bytes.Compare(secret, secretRec) != 0 { log.Fatal("Recovered secret is not the same") diff --git a/ocs/service.go b/ocs/service.go index f5822860ce..dffa434ea6 100644 --- a/ocs/service.go +++ b/ocs/service.go @@ -12,6 +12,8 @@ import ( "os" "time" + "go.dedis.ch/cothority/v3/ocs/certs" + "go.dedis.ch/kyber/v3/sign/schnorr" "go.dedis.ch/kyber/v3/suites" @@ -102,28 +104,28 @@ func (s *Service) AddPolicyCreateOCS(req *AddPolicyCreateOCS) (reply *AddPolicyC // decryption requests. func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { if err = req.verify(); err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } tree := req.Roster.GenerateNaryTreeWithRoot(len(req.Roster.List), s.ServerIdentity()) cfgBuf, err := protobuf.Encode(req) if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } pi, err := s.CreateProtocol(dkgprotocol.Name, tree) if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } setupDKG := pi.(*dkgprotocol.Setup) setupDKG.Wait = true err = setupDKG.SetConfig(&onet.GenericConfig{Data: cfgBuf}) if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } setupDKG.KeyPair = s.getKeyPair() if err := pi.Start(); err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } log.Lvl3("Started DKG-protocol - waiting for done", len(req.Roster.List)) @@ -132,18 +134,18 @@ func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { case <-setupDKG.Finished: shared, dks, err := setupDKG.SharedSecret() if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } ocsID, err := NewOCSID(shared.X) if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } reply = &CreateOCSReply{ OcsID: ocsID, } oid, err = shared.X.MarshalBinary() if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } s.storage.Lock() s.storage.Element[string(oid)] = &storageElement{ @@ -184,11 +186,11 @@ func (s *Service) GetProof(req *GetProof) (reply *GetProofReply, err error) { } msg, err := reply.Proof.Message() if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } sig, err := schnorr.Sign(cothority.Suite, s.ServerIdentity().ServicePrivate(ServiceName), msg) if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } reply.Proof.Signatures = [][]byte{sig} return @@ -221,23 +223,23 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { tree := es.Roster.GenerateNaryTreeWithRoot(nodes, s.ServerIdentity()) pi, err := s.CreateProtocol(NameOCS, tree) if err != nil { - return Erret(err) + return certs.Erret(err) } ocsProto = pi.(*OCS) ocsProto.U, err = dkr.Auth.U() if err != nil { - return Erret(err) + return certs.Erret(err) } X, err := dkr.OcsID.X() if err != nil { - return Erret(err) + return certs.Erret(err) } if err = dkr.Auth.verify(es.PolicyReencrypt, X, ocsProto.U); err != nil { - return Erret(err) + return certs.Erret(err) } ocsProto.Xc, err = dkr.Auth.Xc() if err != nil { - return Erret(err) + return certs.Erret(err) } log.Lvlf2("%v Public key is: %s", s.ServerIdentity(), ocsProto.Xc) ocsProto.VerificationData, err = protobuf.Encode(&dkr.Auth) @@ -267,11 +269,11 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { log.Lvl3("Starting reencryption protocol", ocsProto.TreeNodeInstance.TokenID()) err = ocsProto.SetConfig(&onet.GenericConfig{Data: dkr.OcsID}) if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } err = ocsProto.Start() if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } if !<-ocsProto.Reencrypted { return nil, errors.New("reencryption got refused") @@ -280,10 +282,10 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { reply.XhatEnc, err = share.RecoverCommit(cothority.Suite, ocsProto.Uis, threshold, nodes) if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } if err != nil { - return nil, Erret(err) + return nil, certs.Erret(err) } log.Lvl3("Successfully reencrypted the key") return @@ -594,11 +596,11 @@ func (s *Service) verifyReencryption(rc *MessageReencrypt) bool { var arc AuthReencrypt err := protobuf.DecodeWithConstructors(*rc.VerificationData, &arc, network.DefaultConstructors(cothority.Suite)) if err != nil { - return Erret(err) + return certs.Erret(err) } Xc, err := arc.Xc() if err != nil { - return Erret(err) + return certs.Erret(err) } if !Xc.Equal(rc.Xc) { return errors.New("xcs don't match up") diff --git a/ocs/struct.go b/ocs/struct.go index 9c39954c8c..e288f111df 100644 --- a/ocs/struct.go +++ b/ocs/struct.go @@ -5,7 +5,7 @@ import ( "crypto/x509" "errors" - "go.dedis.ch/cothority/v3/ocs/libtest" + "go.dedis.ch/cothority/v3/ocs/certs" "go.dedis.ch/cothority/v3" "go.dedis.ch/kyber/v3/sign/schnorr" @@ -32,12 +32,12 @@ func (op OCSProof) Verify() error { } msg, err := op.Message() if err != nil { - return libtest.Erret(err) + return certs.Erret(err) } for i, si := range op.Roster.List { err := schnorr.Verify(cothority.Suite, si.ServicePublic(ServiceName), msg, op.Signatures[i]) if err != nil { - return libtest.Erret(err) + return certs.Erret(err) } } return nil @@ -53,7 +53,7 @@ func (op OCSProof) Message() ([]byte, error) { } buf, err := protobuf.Encode(&coc) if err != nil { - return nil, libtest.Erret(err) + return nil, certs.Erret(err) } hash.Write(buf) return hash.Sum(nil), nil @@ -79,7 +79,7 @@ func (px PolicyX509Cert) verify(r onet.Roster) error { } func (px PolicyByzCoin) verify(r onet.Roster) error { - return libtest.Erret(errors.New("not yet implemented")) + return certs.Erret(errors.New("not yet implemented")) } func (ar AuthReencrypt) verify(p Policy, X, U kyber.Point) error { @@ -88,23 +88,19 @@ func (ar AuthReencrypt) verify(p Policy, X, U kyber.Point) error { } root, err := x509.ParseCertificate(p.X509Cert.CA[0]) if err != nil { - return libtest.Erret(err) + return certs.Erret(err) } auth, err := x509.ParseCertificate(ar.X509Cert.Certificates[0]) if err != nil { - return libtest.Erret(err) + return certs.Erret(err) } - ocsID, err := NewOCSID(X) - if err != nil { - return libtest.Erret(err) - } - return libtest.Erret(Verify(root, auth, ocsID, U)) + return certs.Erret(certs.Verify(root, auth, X, U)) } func (ar AuthReencrypt) Xc() (kyber.Point, error) { if ar.X509Cert != nil { - return getPointFromCert(ar.X509Cert.Certificates[0], EphemeralKeyOID) + return certs.GetPointFromCert(ar.X509Cert.Certificates[0], certs.EphemeralKeyOID) } if ar.ByzCoin != nil { return nil, errors.New("can't get ephemeral key from ByzCoin yet") @@ -121,3 +117,13 @@ func (ar AuthReencrypt) U() (kyber.Point, error) { } return nil, errors.New("need to have authentication for X509 or ByzCoin") } + +func NewOCSID(X kyber.Point) (OCSID, error) { + return X.MarshalBinary() +} + +func (ocs OCSID) X() (kyber.Point, error) { + X := cothority.Suite.Point() + err := certs.Erret(X.UnmarshalBinary(ocs)) + return X, err +} From 2e8e7d7be4251d110ca5e468f501a62b04abba8a Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Mon, 15 Apr 2019 13:32:16 +0200 Subject: [PATCH 14/21] adding picture --- ocs/CalypsoByzCoin.png | Bin 0 -> 121665 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ocs/CalypsoByzCoin.png diff --git a/ocs/CalypsoByzCoin.png b/ocs/CalypsoByzCoin.png new file mode 100644 index 0000000000000000000000000000000000000000..9b4d5d2da6184c8136a831adf596ac7d66fe38d9 GIT binary patch literal 121665 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 za=�IDSxcIg?5YUv68sYMQD(DvCOJmR*;)ZyfgnOA_h<;Qon60a+||#Z8tKm+qMs zfo(PRt+w|T=ILvh69Vt}tx$_66ejgrh6A;;^c=-|pjJ5&CHEWHB@1~XFP%xTQ7GCg zQTaAC<}Noya&?$@(tf1JQgCR9E^fwGJ&C>GAEnXg5u44rH@;(oXLlA=O4e z*~rY|3(OjN{gy#L86uOZeN!}j#ls?<;kQ<2o>+gv;mi7ihf~{o#%Cd8JiR>!aw(Y$ zuVae!)|2ik>}-~1ibVbyH99{cEhMM5g*$A!;E3lyA$CX?nV*^1tlFLabuyTPrwK~+ z_Q2WN{BDbj^`G+!|Fa?~IyI3H2crr#?E$kEd7?_I?y(K4Fa^a~W#(`!y3~849C0)L zcu8@sdtKez+aY--ocvIOrEIh3E~PJr8%MwG=IFLRM1st8Vf<= z7f8Vgfo0ziSR2SC?eQ`hRuoR$i$Nwul#EOp+TT(6_jExcmStAIs|H;9hCAD`DAxk$ zh@g}-8S!0PR*m{Lp9HFe#baC2hd2Ub`9b&3)jEi*Ewsioo0q z{8JG{bh&%hA9puU1nv+1lZYhzmMR?frEeM?#QWQB*qZ?4Wu!W`>*v#|h#9_oi>G7{2;(tq)-E;sz-G(jyWesqw97vi% z8lJd4jbN%10L*NNQjj}y)$FR*hixRg4)NRp{LEJYd1>{Czlq-_ zP5*LlU@|lTS=&uDcja=C;g7Z9iz4yaD#7FMqcb?rzF&Y+kP;B>a|A$4T>m&;)+R_m zm6BZo;shk&+UGXf5%izkSjB9`IkQh1J{YGQi0FNsWTfQhZG}WPgX(j;!UsA5<-2M? zC2;JPv{~-$#S}s9f8RL>R|xXrPH{DW-_j;N3H#Dq`!B%p3WE;7Yhz z1|wuWPc|fb|0ANIAAp1C!1@ta0*w{-UBn_<;0npKeALuOP|+E$ibH1fV233SowA;$ zePm@9!j~$&via}FWYduC%4W1;_Ss_)*nxUOJ!E+YYkuCPtK2)X!a!{i^b`(dj#Hgr z1ZRx62#9QH9x%xCCHV7R+oJ;EuJ4pww1Nh1JclfF6Hli90$tA?lpIGznKl!>G6}1d zz!7Qm6VURFfdgVk=!OhE=_6Iu@V|4dgGwjlT?S_WqKw`U2x^(5shlrDznknNtkyma zvgZ0d;ov#(a;WYqNarm#$3KG#y?63)rnri^h!>JQzkR^k;#Z~Q#qiKX&Yb97DvS`Z z$DX!&zGH#C;d1|Td2wjXcLT3^P(2(cLS@0=K9i^yJmX?|)bUy@ftnb*@Io=;pj*K* z6BTZ+{dTA*obIx8EfOBw-FozaOOEvp4lkAA!fE5Qg!dQcOI8tCSg~;3@3%YRT53LR zF7kX>{DsR}2Kq4vj!gbqbE0B~x6N@MmuPmsvOgg~ZfITC&@8_gJL6fOp>5RiAebW& c$rC$=p*4l-T_=p5Wr06^k_j Date: Mon, 15 Apr 2019 14:08:45 +0200 Subject: [PATCH 15/21] updated readme --- ocs/Calypso-ocs-access.png | Bin 0 -> 175531 bytes ocs/CalypsoByzCoin.png | Bin 121665 -> 0 bytes ocs/README.md | 6 +++--- 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 ocs/Calypso-ocs-access.png delete mode 100644 ocs/CalypsoByzCoin.png diff --git a/ocs/Calypso-ocs-access.png b/ocs/Calypso-ocs-access.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9b172fe3da0235e6b2d14eec8478bdfa32603e GIT binary patch literal 175531 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 z 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 za=�IDSxcIg?5YUv68sYMQD(DvCOJmR*;)ZyfgnOA_h<;Qon60a+||#Z8tKm+qMs zfo(PRt+w|T=ILvh69Vt}tx$_66ejgrh6A;;^c=-|pjJ5&CHEWHB@1~XFP%xTQ7GCg zQTaAC<}Noya&?$@(tf1JQgCR9E^fwGJ&C>GAEnXg5u44rH@;(oXLlA=O4e z*~rY|3(OjN{gy#L86uOZeN!}j#ls?<;kQ<2o>+gv;mi7ihf~{o#%Cd8JiR>!aw(Y$ zuVae!)|2ik>}-~1ibVbyH99{cEhMM5g*$A!;E3lyA$CX?nV*^1tlFLabuyTPrwK~+ z_Q2WN{BDbj^`G+!|Fa?~IyI3H2crr#?E$kEd7?_I?y(K4Fa^a~W#(`!y3~849C0)L zcu8@sdtKez+aY--ocvIOrEIh3E~PJr8%MwG=IFLRM1st8Vf<= z7f8Vgfo0ziSR2SC?eQ`hRuoR$i$Nwul#EOp+TT(6_jExcmStAIs|H;9hCAD`DAxk$ zh@g}-8S!0PR*m{Lp9HFe#baC2hd2Ub`9b&3)jEi*Ewsioo0q z{8JG{bh&%hA9puU1nv+1lZYhzmMR?frEeM?#QWQB*qZ?4Wu!W`>*v#|h#9_oi>G7{2;(tq)-E;sz-G(jyWesqw97vi% z8lJd4jbN%10L*NNQjj}y)$FR*hixRg4)NRp{LEJYd1>{Czlq-_ zP5*LlU@|lTS=&uDcja=C;g7Z9iz4yaD#7FMqcb?rzF&Y+kP;B>a|A$4T>m&;)+R_m zm6BZo;shk&+UGXf5%izkSjB9`IkQh1J{YGQi0FNsWTfQhZG}WPgX(j;!UsA5<-2M? zC2;JPv{~-$#S}s9f8RL>R|xXrPH{DW-_j;N3H#Dq`!B%p3WE;7Yhz z1|wuWPc|fb|0ANIAAp1C!1@ta0*w{-UBn_<;0npKeALuOP|+E$ibH1fV233SowA;$ zePm@9!j~$&via}FWYduC%4W1;_Ss_)*nxUOJ!E+YYkuCPtK2)X!a!{i^b`(dj#Hgr z1ZRx62#9QH9x%xCCHV7R+oJ;EuJ4pww1Nh1JclfF6Hli90$tA?lpIGznKl!>G6}1d zz!7Qm6VURFfdgVk=!OhE=_6Iu@V|4dgGwjlT?S_WqKw`U2x^(5shlrDznknNtkyma zvgZ0d;ov#(a;WYqNarm#$3KG#y?63)rnri^h!>JQzkR^k;#Z~Q#qiKX&Yb97DvS`Z z$DX!&zGH#C;d1|Td2wjXcLT3^P(2(cLS@0=K9i^yJmX?|)bUy@ftnb*@Io=;pj*K* z6BTZ+{dTA*obIx8EfOBw-FozaOOEvp4lkAA!fE5Qg!dQcOI8tCSg~;3@3%YRT53LR zF7kX>{DsR}2Kq4vj!gbqbE0B~x6N@MmuPmsvOgg~ZfITC&@8_gJL6fOp>5RiAebW& c$rC$=p*4l-T_=p5Wr06^k_j Date: Fri, 26 Apr 2019 08:28:17 +0200 Subject: [PATCH 16/21] Updating protobuf-files --- .../java/ch/epfl/dedis/lib/proto/Calypso.java | 48 +- .../java/ch/epfl/dedis/lib/proto/OCS.java | 14624 +++++++++++----- external/js/cothority/package-lock.json | 41 +- .../js/cothority/src/protobuf/models.json | 2 +- external/proto/calypso.proto | 9 +- external/proto/ocs.proto | 107 +- ocs/proto.go | 1 + proto.sh | 2 +- 8 files changed, 10293 insertions(+), 4541 deletions(-) diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java index 4bf21b15f3..86215a6b56 100644 --- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java +++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/Calypso.java @@ -115,8 +115,9 @@ public interface WriteOrBuilder extends /** *
-     * C is the ElGamal parts for the symmetric key material (might also
-     * contain an IV)
+     * C is the ElGamal part for the symmetric key material, at maximum length
+     * of ed25519.Point.EmbedLen * 8 = 240 bits. An eventual IV must be published
+     * in ExtraData, as it is not necessary to be encrypted.
      * 
* * required bytes c = 6; @@ -124,8 +125,9 @@ public interface WriteOrBuilder extends boolean hasC(); /** *
-     * C is the ElGamal parts for the symmetric key material (might also
-     * contain an IV)
+     * C is the ElGamal part for the symmetric key material, at maximum length
+     * of ed25519.Point.EmbedLen * 8 = 240 bits. An eventual IV must be published
+     * in ExtraData, as it is not necessary to be encrypted.
      * 
* * required bytes c = 6; @@ -420,8 +422,9 @@ public com.google.protobuf.ByteString getF() { private com.google.protobuf.ByteString c_; /** *
-     * C is the ElGamal parts for the symmetric key material (might also
-     * contain an IV)
+     * C is the ElGamal part for the symmetric key material, at maximum length
+     * of ed25519.Point.EmbedLen * 8 = 240 bits. An eventual IV must be published
+     * in ExtraData, as it is not necessary to be encrypted.
      * 
* * required bytes c = 6; @@ -431,8 +434,9 @@ public boolean hasC() { } /** *
-     * C is the ElGamal parts for the symmetric key material (might also
-     * contain an IV)
+     * C is the ElGamal part for the symmetric key material, at maximum length
+     * of ed25519.Point.EmbedLen * 8 = 240 bits. An eventual IV must be published
+     * in ExtraData, as it is not necessary to be encrypted.
      * 
* * required bytes c = 6; @@ -1308,8 +1312,9 @@ public Builder clearF() { private com.google.protobuf.ByteString c_ = com.google.protobuf.ByteString.EMPTY; /** *
-       * C is the ElGamal parts for the symmetric key material (might also
-       * contain an IV)
+       * C is the ElGamal part for the symmetric key material, at maximum length
+       * of ed25519.Point.EmbedLen * 8 = 240 bits. An eventual IV must be published
+       * in ExtraData, as it is not necessary to be encrypted.
        * 
* * required bytes c = 6; @@ -1319,8 +1324,9 @@ public boolean hasC() { } /** *
-       * C is the ElGamal parts for the symmetric key material (might also
-       * contain an IV)
+       * C is the ElGamal part for the symmetric key material, at maximum length
+       * of ed25519.Point.EmbedLen * 8 = 240 bits. An eventual IV must be published
+       * in ExtraData, as it is not necessary to be encrypted.
        * 
* * required bytes c = 6; @@ -1330,8 +1336,9 @@ public com.google.protobuf.ByteString getC() { } /** *
-       * C is the ElGamal parts for the symmetric key material (might also
-       * contain an IV)
+       * C is the ElGamal part for the symmetric key material, at maximum length
+       * of ed25519.Point.EmbedLen * 8 = 240 bits. An eventual IV must be published
+       * in ExtraData, as it is not necessary to be encrypted.
        * 
* * required bytes c = 6; @@ -1347,8 +1354,9 @@ public Builder setC(com.google.protobuf.ByteString value) { } /** *
-       * C is the ElGamal parts for the symmetric key material (might also
-       * contain an IV)
+       * C is the ElGamal part for the symmetric key material, at maximum length
+       * of ed25519.Point.EmbedLen * 8 = 240 bits. An eventual IV must be published
+       * in ExtraData, as it is not necessary to be encrypted.
        * 
* * required bytes c = 6; @@ -3097,7 +3105,7 @@ public interface CreateLTSOrBuilder extends } /** *
-   * CreateLTS is used to start a DKG and store the private keys in each node.
+   * CreateOCS is used to start a DKG and store the private keys in each node.
    * Prior to using this request, the Calypso roster must be recorded on the
    * ByzCoin blockchain in the instance specified by InstanceID.
    * 
@@ -3377,7 +3385,7 @@ protected Builder newBuilderForType( } /** *
-     * CreateLTS is used to start a DKG and store the private keys in each node.
+     * CreateOCS is used to start a DKG and store the private keys in each node.
      * Prior to using this request, the Calypso roster must be recorded on the
      * ByzCoin blockchain in the instance specified by InstanceID.
      * 
@@ -5589,7 +5597,7 @@ public interface DecryptKeyOrBuilder extends } /** *
-   * DecryptKey is sent by a reader after he successfully stored a 'Read' request
+   * Reencrypt is sent by a reader after he successfully stored a 'Read' request
    * in byzcoin Client.
    * 
* @@ -5950,7 +5958,7 @@ protected Builder newBuilderForType( } /** *
-     * DecryptKey is sent by a reader after he successfully stored a 'Read' request
+     * Reencrypt is sent by a reader after he successfully stored a 'Read' request
      * in byzcoin Client.
      * 
* diff --git a/external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java b/external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java index 81e292173a..f8935de0a4 100644 --- a/external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java +++ b/external/java/src/main/java/ch/epfl/dedis/lib/proto/OCS.java @@ -14,53 +14,41 @@ public static void registerAllExtensions( registerAllExtensions( (com.google.protobuf.ExtensionRegistryLite) registry); } - public interface CreateOCSOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.CreateOCS) + public interface AddPolicyCreateOCSOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AddPolicyCreateOCS) com.google.protobuf.MessageOrBuilder { /** - * required .onet.Roster roster = 1; - */ - boolean hasRoster(); - /** - * required .onet.Roster roster = 1; - */ - ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster(); - /** - * required .onet.Roster roster = 1; - */ - ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder(); - - /** - * required .ocs.Policy policy = 2; + * required .ocs.Policy create = 1; */ - boolean hasPolicy(); + boolean hasCreate(); /** - * required .ocs.Policy policy = 2; + * required .ocs.Policy create = 1; */ - ch.epfl.dedis.lib.proto.OCS.Policy getPolicy(); + ch.epfl.dedis.lib.proto.OCS.Policy getCreate(); /** - * required .ocs.Policy policy = 2; + * required .ocs.Policy create = 1; */ - ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyOrBuilder(); + ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getCreateOrBuilder(); } /** *
-   * CreateOCS is sent to the service to request a new OCS cothority.
+   * AddPolicyCreateOCS is sent by a local admin to add a rule to define who is
+   * authorized to create a new OCS.
    * 
* - * Protobuf type {@code ocs.CreateOCS} + * Protobuf type {@code ocs.AddPolicyCreateOCS} */ - public static final class CreateOCS extends + public static final class AddPolicyCreateOCS extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.CreateOCS) - CreateOCSOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AddPolicyCreateOCS) + AddPolicyCreateOCSOrBuilder { private static final long serialVersionUID = 0L; - // Use CreateOCS.newBuilder() to construct. - private CreateOCS(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AddPolicyCreateOCS.newBuilder() to construct. + private AddPolicyCreateOCS(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private CreateOCS() { + private AddPolicyCreateOCS() { } @java.lang.Override @@ -68,7 +56,7 @@ private CreateOCS() { getUnknownFields() { return this.unknownFields; } - private CreateOCS( + private AddPolicyCreateOCS( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -88,31 +76,18 @@ private CreateOCS( done = true; break; case 10: { - ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null; + ch.epfl.dedis.lib.proto.OCS.Policy.Builder subBuilder = null; if (((bitField0_ & 0x00000001) != 0)) { - subBuilder = roster_.toBuilder(); + subBuilder = create_.toBuilder(); } - roster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry); + create_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Policy.parser(), extensionRegistry); if (subBuilder != null) { - subBuilder.mergeFrom(roster_); - roster_ = subBuilder.buildPartial(); + subBuilder.mergeFrom(create_); + create_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000001; break; } - case 18: { - ch.epfl.dedis.lib.proto.OCS.Policy.Builder subBuilder = null; - if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = policy_.toBuilder(); - } - policy_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Policy.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(policy_); - policy_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000002; - break; - } default: { if (!parseUnknownField( input, unknownFields, extensionRegistry, tag)) { @@ -134,58 +109,37 @@ private CreateOCS( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AddPolicyCreateOCS_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AddPolicyCreateOCS_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.CreateOCS.class, ch.epfl.dedis.lib.proto.OCS.CreateOCS.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS.class, ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS.Builder.class); } private int bitField0_; - public static final int ROSTER_FIELD_NUMBER = 1; - private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_; + public static final int CREATE_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OCS.Policy create_; /** - * required .onet.Roster roster = 1; + * required .ocs.Policy create = 1; */ - public boolean hasRoster() { + public boolean hasCreate() { return ((bitField0_ & 0x00000001) != 0); } /** - * required .onet.Roster roster = 1; - */ - public ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster() { - return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; - } - /** - * required .onet.Roster roster = 1; - */ - public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() { - return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; - } - - public static final int POLICY_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.OCS.Policy policy_; - /** - * required .ocs.Policy policy = 2; - */ - public boolean hasPolicy() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * required .ocs.Policy policy = 2; + * required .ocs.Policy create = 1; */ - public ch.epfl.dedis.lib.proto.OCS.Policy getPolicy() { - return policy_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policy_; + public ch.epfl.dedis.lib.proto.OCS.Policy getCreate() { + return create_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : create_; } /** - * required .ocs.Policy policy = 2; + * required .ocs.Policy create = 1; */ - public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyOrBuilder() { - return policy_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policy_; + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getCreateOrBuilder() { + return create_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : create_; } private byte memoizedIsInitialized = -1; @@ -195,19 +149,11 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasRoster()) { + if (!hasCreate()) { memoizedIsInitialized = 0; return false; } - if (!hasPolicy()) { - memoizedIsInitialized = 0; - return false; - } - if (!getRoster().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } - if (!getPolicy().isInitialized()) { + if (!getCreate().isInitialized()) { memoizedIsInitialized = 0; return false; } @@ -219,10 +165,7 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeMessage(1, getRoster()); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getPolicy()); + output.writeMessage(1, getCreate()); } unknownFields.writeTo(output); } @@ -235,11 +178,7 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, getRoster()); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getPolicy()); + .computeMessageSize(1, getCreate()); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -251,20 +190,15 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCS)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.CreateOCS other = (ch.epfl.dedis.lib.proto.OCS.CreateOCS) obj; + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS other = (ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS) obj; - if (hasRoster() != other.hasRoster()) return false; - if (hasRoster()) { - if (!getRoster() - .equals(other.getRoster())) return false; - } - if (hasPolicy() != other.hasPolicy()) return false; - if (hasPolicy()) { - if (!getPolicy() - .equals(other.getPolicy())) return false; + if (hasCreate() != other.hasCreate()) return false; + if (hasCreate()) { + if (!getCreate() + .equals(other.getCreate())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -277,82 +211,78 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasRoster()) { - hash = (37 * hash) + ROSTER_FIELD_NUMBER; - hash = (53 * hash) + getRoster().hashCode(); - } - if (hasPolicy()) { - hash = (37 * hash) + POLICY_FIELD_NUMBER; - hash = (53 * hash) + getPolicy().hashCode(); + if (hasCreate()) { + hash = (37 * hash) + CREATE_FIELD_NUMBER; + hash = (53 * hash) + getCreate().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -365,7 +295,7 @@ public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.CreateOCS prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -382,29 +312,30 @@ protected Builder newBuilderForType( } /** *
-     * CreateOCS is sent to the service to request a new OCS cothority.
+     * AddPolicyCreateOCS is sent by a local admin to add a rule to define who is
+     * authorized to create a new OCS.
      * 
* - * Protobuf type {@code ocs.CreateOCS} + * Protobuf type {@code ocs.AddPolicyCreateOCS} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.CreateOCS) - ch.epfl.dedis.lib.proto.OCS.CreateOCSOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AddPolicyCreateOCS) + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AddPolicyCreateOCS_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AddPolicyCreateOCS_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.CreateOCS.class, ch.epfl.dedis.lib.proto.OCS.CreateOCS.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS.class, ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.CreateOCS.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -417,42 +348,35 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { - getRosterFieldBuilder(); - getPolicyFieldBuilder(); + getCreateFieldBuilder(); } } @java.lang.Override public Builder clear() { super.clear(); - if (rosterBuilder_ == null) { - roster_ = null; + if (createBuilder_ == null) { + create_ = null; } else { - rosterBuilder_.clear(); + createBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000001); - if (policyBuilder_ == null) { - policy_ = null; - } else { - policyBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AddPolicyCreateOCS_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.CreateOCS getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.CreateOCS.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.CreateOCS build() { - ch.epfl.dedis.lib.proto.OCS.CreateOCS result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS build() { + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -460,26 +384,18 @@ public ch.epfl.dedis.lib.proto.OCS.CreateOCS build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.CreateOCS buildPartial() { - ch.epfl.dedis.lib.proto.OCS.CreateOCS result = new ch.epfl.dedis.lib.proto.OCS.CreateOCS(this); + public ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS result = new ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { - if (rosterBuilder_ == null) { - result.roster_ = roster_; + if (createBuilder_ == null) { + result.create_ = create_; } else { - result.roster_ = rosterBuilder_.build(); + result.create_ = createBuilder_.build(); } to_bitField0_ |= 0x00000001; } - if (((from_bitField0_ & 0x00000002) != 0)) { - if (policyBuilder_ == null) { - result.policy_ = policy_; - } else { - result.policy_ = policyBuilder_.build(); - } - to_bitField0_ |= 0x00000002; - } result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -519,21 +435,18 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCS) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.CreateOCS)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.CreateOCS other) { - if (other == ch.epfl.dedis.lib.proto.OCS.CreateOCS.getDefaultInstance()) return this; - if (other.hasRoster()) { - mergeRoster(other.getRoster()); - } - if (other.hasPolicy()) { - mergePolicy(other.getPolicy()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS.getDefaultInstance()) return this; + if (other.hasCreate()) { + mergeCreate(other.getCreate()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -542,16 +455,10 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.CreateOCS other) { @java.lang.Override public final boolean isInitialized() { - if (!hasRoster()) { - return false; - } - if (!hasPolicy()) { - return false; - } - if (!getRoster().isInitialized()) { + if (!hasCreate()) { return false; } - if (!getPolicy().isInitialized()) { + if (!getCreate().isInitialized()) { return false; } return true; @@ -562,11 +469,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.CreateOCS parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.CreateOCS) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -577,339 +484,198 @@ public Builder mergeFrom( } private int bitField0_; - private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_; + private ch.epfl.dedis.lib.proto.OCS.Policy create_; private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> rosterBuilder_; + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> createBuilder_; /** - * required .onet.Roster roster = 1; + * required .ocs.Policy create = 1; */ - public boolean hasRoster() { + public boolean hasCreate() { return ((bitField0_ & 0x00000001) != 0); } /** - * required .onet.Roster roster = 1; + * required .ocs.Policy create = 1; */ - public ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster() { - if (rosterBuilder_ == null) { - return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; + public ch.epfl.dedis.lib.proto.OCS.Policy getCreate() { + if (createBuilder_ == null) { + return create_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : create_; } else { - return rosterBuilder_.getMessage(); + return createBuilder_.getMessage(); } } /** - * required .onet.Roster roster = 1; + * required .ocs.Policy create = 1; */ - public Builder setRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { - if (rosterBuilder_ == null) { + public Builder setCreate(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (createBuilder_ == null) { if (value == null) { throw new NullPointerException(); } - roster_ = value; + create_ = value; onChanged(); } else { - rosterBuilder_.setMessage(value); + createBuilder_.setMessage(value); } bitField0_ |= 0x00000001; return this; } /** - * required .onet.Roster roster = 1; + * required .ocs.Policy create = 1; */ - public Builder setRoster( - ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder builderForValue) { - if (rosterBuilder_ == null) { - roster_ = builderForValue.build(); + public Builder setCreate( + ch.epfl.dedis.lib.proto.OCS.Policy.Builder builderForValue) { + if (createBuilder_ == null) { + create_ = builderForValue.build(); onChanged(); } else { - rosterBuilder_.setMessage(builderForValue.build()); + createBuilder_.setMessage(builderForValue.build()); } bitField0_ |= 0x00000001; return this; } /** - * required .onet.Roster roster = 1; + * required .ocs.Policy create = 1; */ - public Builder mergeRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { - if (rosterBuilder_ == null) { + public Builder mergeCreate(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (createBuilder_ == null) { if (((bitField0_ & 0x00000001) != 0) && - roster_ != null && - roster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) { - roster_ = - ch.epfl.dedis.lib.proto.OnetProto.Roster.newBuilder(roster_).mergeFrom(value).buildPartial(); + create_ != null && + create_ != ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) { + create_ = + ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder(create_).mergeFrom(value).buildPartial(); } else { - roster_ = value; + create_ = value; } onChanged(); } else { - rosterBuilder_.mergeFrom(value); + createBuilder_.mergeFrom(value); } bitField0_ |= 0x00000001; return this; } /** - * required .onet.Roster roster = 1; + * required .ocs.Policy create = 1; */ - public Builder clearRoster() { - if (rosterBuilder_ == null) { - roster_ = null; + public Builder clearCreate() { + if (createBuilder_ == null) { + create_ = null; onChanged(); } else { - rosterBuilder_.clear(); + createBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000001); return this; } /** - * required .onet.Roster roster = 1; + * required .ocs.Policy create = 1; */ - public ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder getRosterBuilder() { + public ch.epfl.dedis.lib.proto.OCS.Policy.Builder getCreateBuilder() { bitField0_ |= 0x00000001; onChanged(); - return getRosterFieldBuilder().getBuilder(); + return getCreateFieldBuilder().getBuilder(); } /** - * required .onet.Roster roster = 1; + * required .ocs.Policy create = 1; */ - public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() { - if (rosterBuilder_ != null) { - return rosterBuilder_.getMessageOrBuilder(); + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getCreateOrBuilder() { + if (createBuilder_ != null) { + return createBuilder_.getMessageOrBuilder(); } else { - return roster_ == null ? - ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; + return create_ == null ? + ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : create_; } } /** - * required .onet.Roster roster = 1; + * required .ocs.Policy create = 1; */ private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> - getRosterFieldBuilder() { - if (rosterBuilder_ == null) { - rosterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder>( - getRoster(), + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> + getCreateFieldBuilder() { + if (createBuilder_ == null) { + createBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder>( + getCreate(), getParentForChildren(), isClean()); - roster_ = null; + create_ = null; } - return rosterBuilder_; - } - - private ch.epfl.dedis.lib.proto.OCS.Policy policy_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> policyBuilder_; - /** - * required .ocs.Policy policy = 2; - */ - public boolean hasPolicy() { - return ((bitField0_ & 0x00000002) != 0); + return createBuilder_; } - /** - * required .ocs.Policy policy = 2; - */ - public ch.epfl.dedis.lib.proto.OCS.Policy getPolicy() { - if (policyBuilder_ == null) { - return policy_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policy_; - } else { - return policyBuilder_.getMessage(); - } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); } - /** - * required .ocs.Policy policy = 2; - */ - public Builder setPolicy(ch.epfl.dedis.lib.proto.OCS.Policy value) { - if (policyBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - policy_ = value; - onChanged(); - } else { - policyBuilder_.setMessage(value); - } - bitField0_ |= 0x00000002; - return this; + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); } - /** - * required .ocs.Policy policy = 2; - */ - public Builder setPolicy( - ch.epfl.dedis.lib.proto.OCS.Policy.Builder builderForValue) { - if (policyBuilder_ == null) { - policy_ = builderForValue.build(); - onChanged(); - } else { - policyBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * required .ocs.Policy policy = 2; - */ - public Builder mergePolicy(ch.epfl.dedis.lib.proto.OCS.Policy value) { - if (policyBuilder_ == null) { - if (((bitField0_ & 0x00000002) != 0) && - policy_ != null && - policy_ != ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) { - policy_ = - ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder(policy_).mergeFrom(value).buildPartial(); - } else { - policy_ = value; - } - onChanged(); - } else { - policyBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * required .ocs.Policy policy = 2; - */ - public Builder clearPolicy() { - if (policyBuilder_ == null) { - policy_ = null; - onChanged(); - } else { - policyBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - /** - * required .ocs.Policy policy = 2; - */ - public ch.epfl.dedis.lib.proto.OCS.Policy.Builder getPolicyBuilder() { - bitField0_ |= 0x00000002; - onChanged(); - return getPolicyFieldBuilder().getBuilder(); - } - /** - * required .ocs.Policy policy = 2; - */ - public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyOrBuilder() { - if (policyBuilder_ != null) { - return policyBuilder_.getMessageOrBuilder(); - } else { - return policy_ == null ? - ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policy_; - } - } - /** - * required .ocs.Policy policy = 2; - */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> - getPolicyFieldBuilder() { - if (policyBuilder_ == null) { - policyBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder>( - getPolicy(), - getParentForChildren(), - isClean()); - policy_ = null; - } - return policyBuilder_; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); - } - - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:ocs.CreateOCS) - } - - // @@protoc_insertion_point(class_scope:ocs.CreateOCS) - private static final ch.epfl.dedis.lib.proto.OCS.CreateOCS DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.CreateOCS(); - } - - public static ch.epfl.dedis.lib.proto.OCS.CreateOCS getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public CreateOCS parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new CreateOCS(input, extensionRegistry); + + + // @@protoc_insertion_point(builder_scope:ocs.AddPolicyCreateOCS) + } + + // @@protoc_insertion_point(class_scope:ocs.AddPolicyCreateOCS) + private static final ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS(); + } + + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public AddPolicyCreateOCS parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AddPolicyCreateOCS(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.CreateOCS getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCS getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface CreateOCSReplyOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.CreateOCSReply) + public interface AddPolicyCreateOCSReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AddPolicyCreateOCSReply) com.google.protobuf.MessageOrBuilder { - - /** - * required bytes x = 1; - */ - boolean hasX(); - /** - * required bytes x = 1; - */ - com.google.protobuf.ByteString getX(); - - /** - * required bytes sig = 2; - */ - boolean hasSig(); - /** - * required bytes sig = 2; - */ - com.google.protobuf.ByteString getSig(); } /** *
-   * CreateOCSReply is the reply sent by the conode if the OCS has been
-   * setup correctly. It contains the ID of the OCS, which is the binary
-   * representation of the aggregate public key. It also has the Sig, which
-   * is the collective signature of all nodes on the aggregate public key
-   * and the authentication.
+   * AddPolicyCreateOCSReply is an empty reply if the policy has been successfully
+   * created.
    * 
* - * Protobuf type {@code ocs.CreateOCSReply} + * Protobuf type {@code ocs.AddPolicyCreateOCSReply} */ - public static final class CreateOCSReply extends + public static final class AddPolicyCreateOCSReply extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.CreateOCSReply) - CreateOCSReplyOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AddPolicyCreateOCSReply) + AddPolicyCreateOCSReplyOrBuilder { private static final long serialVersionUID = 0L; - // Use CreateOCSReply.newBuilder() to construct. - private CreateOCSReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AddPolicyCreateOCSReply.newBuilder() to construct. + private AddPolicyCreateOCSReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private CreateOCSReply() { - x_ = com.google.protobuf.ByteString.EMPTY; - sig_ = com.google.protobuf.ByteString.EMPTY; + private AddPolicyCreateOCSReply() { } @java.lang.Override @@ -917,7 +683,7 @@ private CreateOCSReply() { getUnknownFields() { return this.unknownFields; } - private CreateOCSReply( + private AddPolicyCreateOCSReply( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -925,7 +691,6 @@ private CreateOCSReply( if (extensionRegistry == null) { throw new java.lang.NullPointerException(); } - int mutable_bitField0_ = 0; com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet.newBuilder(); try { @@ -936,16 +701,6 @@ private CreateOCSReply( case 0: done = true; break; - case 10: { - bitField0_ |= 0x00000001; - x_ = input.readBytes(); - break; - } - case 18: { - bitField0_ |= 0x00000002; - sig_ = input.readBytes(); - break; - } default: { if (!parseUnknownField( input, unknownFields, extensionRegistry, tag)) { @@ -967,46 +722,15 @@ private CreateOCSReply( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AddPolicyCreateOCSReply_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AddPolicyCreateOCSReply_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.class, ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.Builder.class); - } - - private int bitField0_; - public static final int X_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString x_; - /** - * required bytes x = 1; - */ - public boolean hasX() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * required bytes x = 1; - */ - public com.google.protobuf.ByteString getX() { - return x_; - } - - public static final int SIG_FIELD_NUMBER = 2; - private com.google.protobuf.ByteString sig_; - /** - * required bytes sig = 2; - */ - public boolean hasSig() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * required bytes sig = 2; - */ - public com.google.protobuf.ByteString getSig() { - return sig_; + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply.class, ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply.Builder.class); } private byte memoizedIsInitialized = -1; @@ -1016,14 +740,6 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasX()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasSig()) { - memoizedIsInitialized = 0; - return false; - } memoizedIsInitialized = 1; return true; } @@ -1031,12 +747,6 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, x_); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeBytes(2, sig_); - } unknownFields.writeTo(output); } @@ -1046,14 +756,6 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, x_); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(2, sig_); - } size += unknownFields.getSerializedSize(); memoizedSize = size; return size; @@ -1064,21 +766,11 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCSReply)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.CreateOCSReply other = (ch.epfl.dedis.lib.proto.OCS.CreateOCSReply) obj; + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply other = (ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply) obj; - if (hasX() != other.hasX()) return false; - if (hasX()) { - if (!getX() - .equals(other.getX())) return false; - } - if (hasSig() != other.hasSig()) return false; - if (hasSig()) { - if (!getSig() - .equals(other.getSig())) return false; - } if (!unknownFields.equals(other.unknownFields)) return false; return true; } @@ -1090,82 +782,74 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasX()) { - hash = (37 * hash) + X_FIELD_NUMBER; - hash = (53 * hash) + getX().hashCode(); - } - if (hasSig()) { - hash = (37 * hash) + SIG_FIELD_NUMBER; - hash = (53 * hash) + getSig().hashCode(); - } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1178,7 +862,7 @@ public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.CreateOCSReply prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -1195,33 +879,30 @@ protected Builder newBuilderForType( } /** *
-     * CreateOCSReply is the reply sent by the conode if the OCS has been
-     * setup correctly. It contains the ID of the OCS, which is the binary
-     * representation of the aggregate public key. It also has the Sig, which
-     * is the collective signature of all nodes on the aggregate public key
-     * and the authentication.
+     * AddPolicyCreateOCSReply is an empty reply if the policy has been successfully
+     * created.
      * 
* - * Protobuf type {@code ocs.CreateOCSReply} + * Protobuf type {@code ocs.AddPolicyCreateOCSReply} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.CreateOCSReply) - ch.epfl.dedis.lib.proto.OCS.CreateOCSReplyOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AddPolicyCreateOCSReply) + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReplyOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AddPolicyCreateOCSReply_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AddPolicyCreateOCSReply_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.class, ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply.class, ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -1239,27 +920,23 @@ private void maybeForceBuilderInitialization() { @java.lang.Override public Builder clear() { super.clear(); - x_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000001); - sig_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000002); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AddPolicyCreateOCSReply_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply build() { - ch.epfl.dedis.lib.proto.OCS.CreateOCSReply result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply build() { + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -1267,19 +944,8 @@ public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply buildPartial() { - ch.epfl.dedis.lib.proto.OCS.CreateOCSReply result = new ch.epfl.dedis.lib.proto.OCS.CreateOCSReply(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) != 0)) { - to_bitField0_ |= 0x00000001; - } - result.x_ = x_; - if (((from_bitField0_ & 0x00000002) != 0)) { - to_bitField0_ |= 0x00000002; - } - result.sig_ = sig_; - result.bitField0_ = to_bitField0_; + public ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply result = new ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply(this); onBuilt(); return result; } @@ -1318,22 +984,16 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCSReply) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.CreateOCSReply)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.CreateOCSReply other) { - if (other == ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.getDefaultInstance()) return this; - if (other.hasX()) { - setX(other.getX()); - } - if (other.hasSig()) { - setSig(other.getSig()); - } + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply.getDefaultInstance()) return this; this.mergeUnknownFields(other.unknownFields); onChanged(); return this; @@ -1341,12 +1001,6 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.CreateOCSReply other) { @java.lang.Override public final boolean isInitialized() { - if (!hasX()) { - return false; - } - if (!hasSig()) { - return false; - } return true; } @@ -1355,11 +1009,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.CreateOCSReply) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -1368,77 +1022,6 @@ public Builder mergeFrom( } return this; } - private int bitField0_; - - private com.google.protobuf.ByteString x_ = com.google.protobuf.ByteString.EMPTY; - /** - * required bytes x = 1; - */ - public boolean hasX() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * required bytes x = 1; - */ - public com.google.protobuf.ByteString getX() { - return x_; - } - /** - * required bytes x = 1; - */ - public Builder setX(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - x_ = value; - onChanged(); - return this; - } - /** - * required bytes x = 1; - */ - public Builder clearX() { - bitField0_ = (bitField0_ & ~0x00000001); - x_ = getDefaultInstance().getX(); - onChanged(); - return this; - } - - private com.google.protobuf.ByteString sig_ = com.google.protobuf.ByteString.EMPTY; - /** - * required bytes sig = 2; - */ - public boolean hasSig() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * required bytes sig = 2; - */ - public com.google.protobuf.ByteString getSig() { - return sig_; - } - /** - * required bytes sig = 2; - */ - public Builder setSig(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000002; - sig_ = value; - onChanged(); - return this; - } - /** - * required bytes sig = 2; - */ - public Builder clearSig() { - bitField0_ = (bitField0_ & ~0x00000002); - sig_ = getDefaultInstance().getSig(); - onChanged(); - return this; - } @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { @@ -1452,93 +1035,112 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.CreateOCSReply) + // @@protoc_insertion_point(builder_scope:ocs.AddPolicyCreateOCSReply) } - // @@protoc_insertion_point(class_scope:ocs.CreateOCSReply) - private static final ch.epfl.dedis.lib.proto.OCS.CreateOCSReply DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AddPolicyCreateOCSReply) + private static final ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.CreateOCSReply(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply(); } - public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public CreateOCSReply parsePartialFrom( + public AddPolicyCreateOCSReply parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new CreateOCSReply(input, extensionRegistry); + return new AddPolicyCreateOCSReply(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AddPolicyCreateOCSReply getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface ReencryptOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.Reencrypt) + public interface CreateOCSOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.CreateOCS) com.google.protobuf.MessageOrBuilder { /** - * required bytes x = 1; + * required .onet.Roster roster = 1; */ - boolean hasX(); + boolean hasRoster(); /** - * required bytes x = 1; + * required .onet.Roster roster = 1; */ - com.google.protobuf.ByteString getX(); + ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster(); + /** + * required .onet.Roster roster = 1; + */ + ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder(); /** - * required .ocs.AuthReencrypt auth = 2; + * required .ocs.Policy policyreencrypt = 2; */ - boolean hasAuth(); + boolean hasPolicyreencrypt(); /** - * required .ocs.AuthReencrypt auth = 2; + * required .ocs.Policy policyreencrypt = 2; */ - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getAuth(); + ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt(); /** - * required .ocs.AuthReencrypt auth = 2; + * required .ocs.Policy policyreencrypt = 2; */ - ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder getAuthOrBuilder(); + ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder(); + + /** + * required .ocs.Policy policyreshare = 3; + */ + boolean hasPolicyreshare(); + /** + * required .ocs.Policy policyreshare = 3; + */ + ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare(); + /** + * required .ocs.Policy policyreshare = 3; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder(); } /** *
-   * Reencrypt is sent to the service to request a re-encryption of the
-   * secret given in AuthReencrypt. AuthReencrypt must also contain the proof that the
-   * request is valid, as well as the ephemeral key, to which the secret
-   * will be re-encrypted.
+   * CreateOCS is sent to the service to request a new OCS cothority.
+   * It holds the two policies necessary to define an OCS: how to
+   * authenticate a reencryption request, and how to authenticate a
+   * resharing request.
+   * In the current form, both policies point to the same structure. If at
+   * a later moment a new access control backend is added, it might be that
+   * the policies will differ for this new backend.
    * 
* - * Protobuf type {@code ocs.Reencrypt} + * Protobuf type {@code ocs.CreateOCS} */ - public static final class Reencrypt extends + public static final class CreateOCS extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.Reencrypt) - ReencryptOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.CreateOCS) + CreateOCSOrBuilder { private static final long serialVersionUID = 0L; - // Use Reencrypt.newBuilder() to construct. - private Reencrypt(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use CreateOCS.newBuilder() to construct. + private CreateOCS(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private Reencrypt() { - x_ = com.google.protobuf.ByteString.EMPTY; + private CreateOCS() { } @java.lang.Override @@ -1546,7 +1148,7 @@ private Reencrypt() { getUnknownFields() { return this.unknownFields; } - private Reencrypt( + private CreateOCS( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -1566,23 +1168,44 @@ private Reencrypt( done = true; break; case 10: { + ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = roster_.toBuilder(); + } + roster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(roster_); + roster_ = subBuilder.buildPartial(); + } bitField0_ |= 0x00000001; - x_ = input.readBytes(); break; } case 18: { - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder subBuilder = null; + ch.epfl.dedis.lib.proto.OCS.Policy.Builder subBuilder = null; if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = auth_.toBuilder(); + subBuilder = policyreencrypt_.toBuilder(); } - auth_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.parser(), extensionRegistry); + policyreencrypt_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Policy.parser(), extensionRegistry); if (subBuilder != null) { - subBuilder.mergeFrom(auth_); - auth_ = subBuilder.buildPartial(); + subBuilder.mergeFrom(policyreencrypt_); + policyreencrypt_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000002; break; } + case 26: { + ch.epfl.dedis.lib.proto.OCS.Policy.Builder subBuilder = null; + if (((bitField0_ & 0x00000004) != 0)) { + subBuilder = policyreshare_.toBuilder(); + } + policyreshare_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Policy.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(policyreshare_); + policyreshare_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000004; + break; + } default: { if (!parseUnknownField( input, unknownFields, extensionRegistry, tag)) { @@ -1604,52 +1227,79 @@ private Reencrypt( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.Reencrypt.class, ch.epfl.dedis.lib.proto.OCS.Reencrypt.Builder.class); + ch.epfl.dedis.lib.proto.OCS.CreateOCS.class, ch.epfl.dedis.lib.proto.OCS.CreateOCS.Builder.class); } private int bitField0_; - public static final int X_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString x_; + public static final int ROSTER_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_; /** - * required bytes x = 1; + * required .onet.Roster roster = 1; */ - public boolean hasX() { + public boolean hasRoster() { return ((bitField0_ & 0x00000001) != 0); } /** - * required bytes x = 1; + * required .onet.Roster roster = 1; */ - public com.google.protobuf.ByteString getX() { - return x_; + public ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster() { + return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; + } + /** + * required .onet.Roster roster = 1; + */ + public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() { + return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; } - public static final int AUTH_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.OCS.AuthReencrypt auth_; + public static final int POLICYREENCRYPT_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.Policy policyreencrypt_; /** - * required .ocs.AuthReencrypt auth = 2; + * required .ocs.Policy policyreencrypt = 2; */ - public boolean hasAuth() { + public boolean hasPolicyreencrypt() { return ((bitField0_ & 0x00000002) != 0); } /** - * required .ocs.AuthReencrypt auth = 2; + * required .ocs.Policy policyreencrypt = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getAuth() { - return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt() { + return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; } /** - * required .ocs.AuthReencrypt auth = 2; + * required .ocs.Policy policyreencrypt = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder getAuthOrBuilder() { - return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder() { + return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + } + + public static final int POLICYRESHARE_FIELD_NUMBER = 3; + private ch.epfl.dedis.lib.proto.OCS.Policy policyreshare_; + /** + * required .ocs.Policy policyreshare = 3; + */ + public boolean hasPolicyreshare() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required .ocs.Policy policyreshare = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare() { + return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + } + /** + * required .ocs.Policy policyreshare = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder() { + return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; } private byte memoizedIsInitialized = -1; @@ -1659,15 +1309,27 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasX()) { + if (!hasRoster()) { memoizedIsInitialized = 0; return false; } - if (!hasAuth()) { + if (!hasPolicyreencrypt()) { memoizedIsInitialized = 0; return false; } - if (!getAuth().isInitialized()) { + if (!hasPolicyreshare()) { + memoizedIsInitialized = 0; + return false; + } + if (!getRoster().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getPolicyreencrypt().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getPolicyreshare().isInitialized()) { memoizedIsInitialized = 0; return false; } @@ -1679,10 +1341,13 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, x_); + output.writeMessage(1, getRoster()); } if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getAuth()); + output.writeMessage(2, getPolicyreencrypt()); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeMessage(3, getPolicyreshare()); } unknownFields.writeTo(output); } @@ -1695,11 +1360,15 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, x_); + .computeMessageSize(1, getRoster()); } if (((bitField0_ & 0x00000002) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getAuth()); + .computeMessageSize(2, getPolicyreencrypt()); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, getPolicyreshare()); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -1711,20 +1380,25 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Reencrypt)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCS)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.Reencrypt other = (ch.epfl.dedis.lib.proto.OCS.Reencrypt) obj; + ch.epfl.dedis.lib.proto.OCS.CreateOCS other = (ch.epfl.dedis.lib.proto.OCS.CreateOCS) obj; - if (hasX() != other.hasX()) return false; - if (hasX()) { - if (!getX() - .equals(other.getX())) return false; + if (hasRoster() != other.hasRoster()) return false; + if (hasRoster()) { + if (!getRoster() + .equals(other.getRoster())) return false; } - if (hasAuth() != other.hasAuth()) return false; - if (hasAuth()) { - if (!getAuth() - .equals(other.getAuth())) return false; + if (hasPolicyreencrypt() != other.hasPolicyreencrypt()) return false; + if (hasPolicyreencrypt()) { + if (!getPolicyreencrypt() + .equals(other.getPolicyreencrypt())) return false; + } + if (hasPolicyreshare() != other.hasPolicyreshare()) return false; + if (hasPolicyreshare()) { + if (!getPolicyreshare() + .equals(other.getPolicyreshare())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -1737,82 +1411,86 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasX()) { - hash = (37 * hash) + X_FIELD_NUMBER; - hash = (53 * hash) + getX().hashCode(); + if (hasRoster()) { + hash = (37 * hash) + ROSTER_FIELD_NUMBER; + hash = (53 * hash) + getRoster().hashCode(); } - if (hasAuth()) { - hash = (37 * hash) + AUTH_FIELD_NUMBER; - hash = (53 * hash) + getAuth().hashCode(); + if (hasPolicyreencrypt()) { + hash = (37 * hash) + POLICYREENCRYPT_FIELD_NUMBER; + hash = (53 * hash) + getPolicyreencrypt().hashCode(); + } + if (hasPolicyreshare()) { + hash = (37 * hash) + POLICYRESHARE_FIELD_NUMBER; + hash = (53 * hash) + getPolicyreshare().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1825,7 +1503,7 @@ public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Reencrypt prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.CreateOCS prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -1842,32 +1520,35 @@ protected Builder newBuilderForType( } /** *
-     * Reencrypt is sent to the service to request a re-encryption of the
-     * secret given in AuthReencrypt. AuthReencrypt must also contain the proof that the
-     * request is valid, as well as the ephemeral key, to which the secret
-     * will be re-encrypted.
+     * CreateOCS is sent to the service to request a new OCS cothority.
+     * It holds the two policies necessary to define an OCS: how to
+     * authenticate a reencryption request, and how to authenticate a
+     * resharing request.
+     * In the current form, both policies point to the same structure. If at
+     * a later moment a new access control backend is added, it might be that
+     * the policies will differ for this new backend.
      * 
* - * Protobuf type {@code ocs.Reencrypt} + * Protobuf type {@code ocs.CreateOCS} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.Reencrypt) - ch.epfl.dedis.lib.proto.OCS.ReencryptOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.CreateOCS) + ch.epfl.dedis.lib.proto.OCS.CreateOCSOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.Reencrypt.class, ch.epfl.dedis.lib.proto.OCS.Reencrypt.Builder.class); + ch.epfl.dedis.lib.proto.OCS.CreateOCS.class, ch.epfl.dedis.lib.proto.OCS.CreateOCS.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.Reencrypt.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.CreateOCS.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -1880,37 +1561,49 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { - getAuthFieldBuilder(); + getRosterFieldBuilder(); + getPolicyreencryptFieldBuilder(); + getPolicyreshareFieldBuilder(); } } @java.lang.Override public Builder clear() { super.clear(); - x_ = com.google.protobuf.ByteString.EMPTY; + if (rosterBuilder_ == null) { + roster_ = null; + } else { + rosterBuilder_.clear(); + } bitField0_ = (bitField0_ & ~0x00000001); - if (authBuilder_ == null) { - auth_ = null; + if (policyreencryptBuilder_ == null) { + policyreencrypt_ = null; } else { - authBuilder_.clear(); + policyreencryptBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000002); + if (policyreshareBuilder_ == null) { + policyreshare_ = null; + } else { + policyreshareBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCS_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Reencrypt getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.Reencrypt.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.CreateOCS getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.CreateOCS.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Reencrypt build() { - ch.epfl.dedis.lib.proto.OCS.Reencrypt result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.CreateOCS build() { + ch.epfl.dedis.lib.proto.OCS.CreateOCS result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -1918,22 +1611,34 @@ public ch.epfl.dedis.lib.proto.OCS.Reencrypt build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Reencrypt buildPartial() { - ch.epfl.dedis.lib.proto.OCS.Reencrypt result = new ch.epfl.dedis.lib.proto.OCS.Reencrypt(this); + public ch.epfl.dedis.lib.proto.OCS.CreateOCS buildPartial() { + ch.epfl.dedis.lib.proto.OCS.CreateOCS result = new ch.epfl.dedis.lib.proto.OCS.CreateOCS(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { + if (rosterBuilder_ == null) { + result.roster_ = roster_; + } else { + result.roster_ = rosterBuilder_.build(); + } to_bitField0_ |= 0x00000001; } - result.x_ = x_; if (((from_bitField0_ & 0x00000002) != 0)) { - if (authBuilder_ == null) { - result.auth_ = auth_; + if (policyreencryptBuilder_ == null) { + result.policyreencrypt_ = policyreencrypt_; } else { - result.auth_ = authBuilder_.build(); + result.policyreencrypt_ = policyreencryptBuilder_.build(); } to_bitField0_ |= 0x00000002; } + if (((from_bitField0_ & 0x00000004) != 0)) { + if (policyreshareBuilder_ == null) { + result.policyreshare_ = policyreshare_; + } else { + result.policyreshare_ = policyreshareBuilder_.build(); + } + to_bitField0_ |= 0x00000004; + } result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -1973,21 +1678,24 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.Reencrypt) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Reencrypt)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCS) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.CreateOCS)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Reencrypt other) { - if (other == ch.epfl.dedis.lib.proto.OCS.Reencrypt.getDefaultInstance()) return this; - if (other.hasX()) { - setX(other.getX()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.CreateOCS other) { + if (other == ch.epfl.dedis.lib.proto.OCS.CreateOCS.getDefaultInstance()) return this; + if (other.hasRoster()) { + mergeRoster(other.getRoster()); } - if (other.hasAuth()) { - mergeAuth(other.getAuth()); + if (other.hasPolicyreencrypt()) { + mergePolicyreencrypt(other.getPolicyreencrypt()); + } + if (other.hasPolicyreshare()) { + mergePolicyreshare(other.getPolicyreshare()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -1996,13 +1704,22 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Reencrypt other) { @java.lang.Override public final boolean isInitialized() { - if (!hasX()) { + if (!hasRoster()) { return false; } - if (!hasAuth()) { + if (!hasPolicyreencrypt()) { return false; } - if (!getAuth().isInitialized()) { + if (!hasPolicyreshare()) { + return false; + } + if (!getRoster().isInitialized()) { + return false; + } + if (!getPolicyreencrypt().isInitialized()) { + return false; + } + if (!getPolicyreshare().isInitialized()) { return false; } return true; @@ -2013,11 +1730,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.Reencrypt parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.CreateOCS parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Reencrypt) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.CreateOCS) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -2028,244 +1745,447 @@ public Builder mergeFrom( } private int bitField0_; - private com.google.protobuf.ByteString x_ = com.google.protobuf.ByteString.EMPTY; - /** - * required bytes x = 1; - */ - public boolean hasX() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * required bytes x = 1; - */ - public com.google.protobuf.ByteString getX() { - return x_; - } - /** - * required bytes x = 1; - */ - public Builder setX(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - x_ = value; - onChanged(); - return this; - } - /** - * required bytes x = 1; - */ - public Builder clearX() { - bitField0_ = (bitField0_ & ~0x00000001); - x_ = getDefaultInstance().getX(); - onChanged(); - return this; - } - - private ch.epfl.dedis.lib.proto.OCS.AuthReencrypt auth_; + private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_; private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder> authBuilder_; + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> rosterBuilder_; /** - * required .ocs.AuthReencrypt auth = 2; + * required .onet.Roster roster = 1; */ - public boolean hasAuth() { - return ((bitField0_ & 0x00000002) != 0); + public boolean hasRoster() { + return ((bitField0_ & 0x00000001) != 0); } /** - * required .ocs.AuthReencrypt auth = 2; + * required .onet.Roster roster = 1; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getAuth() { - if (authBuilder_ == null) { - return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; + public ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster() { + if (rosterBuilder_ == null) { + return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; } else { - return authBuilder_.getMessage(); + return rosterBuilder_.getMessage(); } } /** - * required .ocs.AuthReencrypt auth = 2; + * required .onet.Roster roster = 1; */ - public Builder setAuth(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt value) { - if (authBuilder_ == null) { + public Builder setRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { + if (rosterBuilder_ == null) { if (value == null) { throw new NullPointerException(); } - auth_ = value; + roster_ = value; onChanged(); } else { - authBuilder_.setMessage(value); + rosterBuilder_.setMessage(value); } - bitField0_ |= 0x00000002; + bitField0_ |= 0x00000001; return this; } /** - * required .ocs.AuthReencrypt auth = 2; + * required .onet.Roster roster = 1; */ - public Builder setAuth( - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder builderForValue) { - if (authBuilder_ == null) { - auth_ = builderForValue.build(); + public Builder setRoster( + ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder builderForValue) { + if (rosterBuilder_ == null) { + roster_ = builderForValue.build(); onChanged(); } else { - authBuilder_.setMessage(builderForValue.build()); + rosterBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .onet.Roster roster = 1; + */ + public Builder mergeRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { + if (rosterBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + roster_ != null && + roster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) { + roster_ = + ch.epfl.dedis.lib.proto.OnetProto.Roster.newBuilder(roster_).mergeFrom(value).buildPartial(); + } else { + roster_ = value; + } + onChanged(); + } else { + rosterBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .onet.Roster roster = 1; + */ + public Builder clearRoster() { + if (rosterBuilder_ == null) { + roster_ = null; + onChanged(); + } else { + rosterBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .onet.Roster roster = 1; + */ + public ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder getRosterBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getRosterFieldBuilder().getBuilder(); + } + /** + * required .onet.Roster roster = 1; + */ + public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() { + if (rosterBuilder_ != null) { + return rosterBuilder_.getMessageOrBuilder(); + } else { + return roster_ == null ? + ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; + } + } + /** + * required .onet.Roster roster = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> + getRosterFieldBuilder() { + if (rosterBuilder_ == null) { + rosterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder>( + getRoster(), + getParentForChildren(), + isClean()); + roster_ = null; + } + return rosterBuilder_; + } + + private ch.epfl.dedis.lib.proto.OCS.Policy policyreencrypt_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> policyreencryptBuilder_; + /** + * required .ocs.Policy policyreencrypt = 2; + */ + public boolean hasPolicyreencrypt() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .ocs.Policy policyreencrypt = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt() { + if (policyreencryptBuilder_ == null) { + return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + } else { + return policyreencryptBuilder_.getMessage(); + } + } + /** + * required .ocs.Policy policyreencrypt = 2; + */ + public Builder setPolicyreencrypt(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreencryptBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + policyreencrypt_ = value; + onChanged(); + } else { + policyreencryptBuilder_.setMessage(value); } bitField0_ |= 0x00000002; return this; } /** - * required .ocs.AuthReencrypt auth = 2; + * required .ocs.Policy policyreencrypt = 2; */ - public Builder mergeAuth(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt value) { - if (authBuilder_ == null) { + public Builder setPolicyreencrypt( + ch.epfl.dedis.lib.proto.OCS.Policy.Builder builderForValue) { + if (policyreencryptBuilder_ == null) { + policyreencrypt_ = builderForValue.build(); + onChanged(); + } else { + policyreencryptBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.Policy policyreencrypt = 2; + */ + public Builder mergePolicyreencrypt(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreencryptBuilder_ == null) { if (((bitField0_ & 0x00000002) != 0) && - auth_ != null && - auth_ != ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance()) { - auth_ = - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.newBuilder(auth_).mergeFrom(value).buildPartial(); + policyreencrypt_ != null && + policyreencrypt_ != ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) { + policyreencrypt_ = + ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder(policyreencrypt_).mergeFrom(value).buildPartial(); } else { - auth_ = value; + policyreencrypt_ = value; } onChanged(); } else { - authBuilder_.mergeFrom(value); + policyreencryptBuilder_.mergeFrom(value); } bitField0_ |= 0x00000002; return this; } /** - * required .ocs.AuthReencrypt auth = 2; + * required .ocs.Policy policyreencrypt = 2; */ - public Builder clearAuth() { - if (authBuilder_ == null) { - auth_ = null; + public Builder clearPolicyreencrypt() { + if (policyreencryptBuilder_ == null) { + policyreencrypt_ = null; onChanged(); } else { - authBuilder_.clear(); + policyreencryptBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000002); return this; } /** - * required .ocs.AuthReencrypt auth = 2; + * required .ocs.Policy policyreencrypt = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder getAuthBuilder() { + public ch.epfl.dedis.lib.proto.OCS.Policy.Builder getPolicyreencryptBuilder() { bitField0_ |= 0x00000002; onChanged(); - return getAuthFieldBuilder().getBuilder(); + return getPolicyreencryptFieldBuilder().getBuilder(); } /** - * required .ocs.AuthReencrypt auth = 2; + * required .ocs.Policy policyreencrypt = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder getAuthOrBuilder() { - if (authBuilder_ != null) { - return authBuilder_.getMessageOrBuilder(); + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder() { + if (policyreencryptBuilder_ != null) { + return policyreencryptBuilder_.getMessageOrBuilder(); } else { - return auth_ == null ? - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; + return policyreencrypt_ == null ? + ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; } } /** - * required .ocs.AuthReencrypt auth = 2; + * required .ocs.Policy policyreencrypt = 2; */ private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder> - getAuthFieldBuilder() { - if (authBuilder_ == null) { - authBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder>( - getAuth(), + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> + getPolicyreencryptFieldBuilder() { + if (policyreencryptBuilder_ == null) { + policyreencryptBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder>( + getPolicyreencrypt(), getParentForChildren(), isClean()); - auth_ = null; + policyreencrypt_ = null; } - return authBuilder_; - } - @java.lang.Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFields(unknownFields); + return policyreencryptBuilder_; } - @java.lang.Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); + private ch.epfl.dedis.lib.proto.OCS.Policy policyreshare_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> policyreshareBuilder_; + /** + * required .ocs.Policy policyreshare = 3; + */ + public boolean hasPolicyreshare() { + return ((bitField0_ & 0x00000004) != 0); } - - - // @@protoc_insertion_point(builder_scope:ocs.Reencrypt) - } - - // @@protoc_insertion_point(class_scope:ocs.Reencrypt) - private static final ch.epfl.dedis.lib.proto.OCS.Reencrypt DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Reencrypt(); - } - - public static ch.epfl.dedis.lib.proto.OCS.Reencrypt getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override - public Reencrypt parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new Reencrypt(input, extensionRegistry); + /** + * required .ocs.Policy policyreshare = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare() { + if (policyreshareBuilder_ == null) { + return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + } else { + return policyreshareBuilder_.getMessage(); + } } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Reencrypt getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - - } - - public interface ReencryptReplyOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.ReencryptReply) - com.google.protobuf.MessageOrBuilder { - - /** - * required bytes xhat = 1; - */ - boolean hasXhat(); - /** - * required bytes xhat = 1; + /** + * required .ocs.Policy policyreshare = 3; + */ + public Builder setPolicyreshare(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreshareBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + policyreshare_ = value; + onChanged(); + } else { + policyreshareBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .ocs.Policy policyreshare = 3; + */ + public Builder setPolicyreshare( + ch.epfl.dedis.lib.proto.OCS.Policy.Builder builderForValue) { + if (policyreshareBuilder_ == null) { + policyreshare_ = builderForValue.build(); + onChanged(); + } else { + policyreshareBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .ocs.Policy policyreshare = 3; + */ + public Builder mergePolicyreshare(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreshareBuilder_ == null) { + if (((bitField0_ & 0x00000004) != 0) && + policyreshare_ != null && + policyreshare_ != ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) { + policyreshare_ = + ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder(policyreshare_).mergeFrom(value).buildPartial(); + } else { + policyreshare_ = value; + } + onChanged(); + } else { + policyreshareBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .ocs.Policy policyreshare = 3; + */ + public Builder clearPolicyreshare() { + if (policyreshareBuilder_ == null) { + policyreshare_ = null; + onChanged(); + } else { + policyreshareBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + /** + * required .ocs.Policy policyreshare = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy.Builder getPolicyreshareBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getPolicyreshareFieldBuilder().getBuilder(); + } + /** + * required .ocs.Policy policyreshare = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder() { + if (policyreshareBuilder_ != null) { + return policyreshareBuilder_.getMessageOrBuilder(); + } else { + return policyreshare_ == null ? + ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + } + } + /** + * required .ocs.Policy policyreshare = 3; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> + getPolicyreshareFieldBuilder() { + if (policyreshareBuilder_ == null) { + policyreshareBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder>( + getPolicyreshare(), + getParentForChildren(), + isClean()); + policyreshare_ = null; + } + return policyreshareBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.CreateOCS) + } + + // @@protoc_insertion_point(class_scope:ocs.CreateOCS) + private static final ch.epfl.dedis.lib.proto.OCS.CreateOCS DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.CreateOCS(); + } + + public static ch.epfl.dedis.lib.proto.OCS.CreateOCS getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public CreateOCS parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CreateOCS(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.CreateOCS getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface CreateOCSReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.CreateOCSReply) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes ocsid = 1; + */ + boolean hasOcsid(); + /** + * required bytes ocsid = 1; */ - com.google.protobuf.ByteString getXhat(); + com.google.protobuf.ByteString getOcsid(); } /** *
-   * MessageReencryptReply is the reply if the re-encryption is successful, and
-   * it contains XHat, which is the secret re-encrypted to the ephemeral
-   * key given in AuthReencrypt.
+   * CreateOCSReply is the reply sent by the conode if the OCS has been
+   * setup correctly. It contains the ID of the OCS, which is the binary
+   * representation of the aggregate public key. It also has the Sig, which
+   * is the collective signature of all nodes on the aggregate public key
+   * and the authentication.
    * 
* - * Protobuf type {@code ocs.ReencryptReply} + * Protobuf type {@code ocs.CreateOCSReply} */ - public static final class ReencryptReply extends + public static final class CreateOCSReply extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.ReencryptReply) - ReencryptReplyOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.CreateOCSReply) + CreateOCSReplyOrBuilder { private static final long serialVersionUID = 0L; - // Use ReencryptReply.newBuilder() to construct. - private ReencryptReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use CreateOCSReply.newBuilder() to construct. + private CreateOCSReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private ReencryptReply() { - xhat_ = com.google.protobuf.ByteString.EMPTY; + private CreateOCSReply() { + ocsid_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -2273,7 +2193,7 @@ private ReencryptReply() { getUnknownFields() { return this.unknownFields; } - private ReencryptReply( + private CreateOCSReply( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -2294,7 +2214,7 @@ private ReencryptReply( break; case 10: { bitField0_ |= 0x00000001; - xhat_ = input.readBytes(); + ocsid_ = input.readBytes(); break; } default: { @@ -2318,31 +2238,31 @@ private ReencryptReply( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.ReencryptReply.class, ch.epfl.dedis.lib.proto.OCS.ReencryptReply.Builder.class); + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.class, ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.Builder.class); } private int bitField0_; - public static final int XHAT_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString xhat_; + public static final int OCSID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString ocsid_; /** - * required bytes xhat = 1; + * required bytes ocsid = 1; */ - public boolean hasXhat() { + public boolean hasOcsid() { return ((bitField0_ & 0x00000001) != 0); } /** - * required bytes xhat = 1; + * required bytes ocsid = 1; */ - public com.google.protobuf.ByteString getXhat() { - return xhat_; + public com.google.protobuf.ByteString getOcsid() { + return ocsid_; } private byte memoizedIsInitialized = -1; @@ -2352,7 +2272,7 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasXhat()) { + if (!hasOcsid()) { memoizedIsInitialized = 0; return false; } @@ -2364,7 +2284,7 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, xhat_); + output.writeBytes(1, ocsid_); } unknownFields.writeTo(output); } @@ -2377,7 +2297,7 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, xhat_); + .computeBytesSize(1, ocsid_); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -2389,15 +2309,15 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.ReencryptReply)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCSReply)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.ReencryptReply other = (ch.epfl.dedis.lib.proto.OCS.ReencryptReply) obj; + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply other = (ch.epfl.dedis.lib.proto.OCS.CreateOCSReply) obj; - if (hasXhat() != other.hasXhat()) return false; - if (hasXhat()) { - if (!getXhat() - .equals(other.getXhat())) return false; + if (hasOcsid() != other.hasOcsid()) return false; + if (hasOcsid()) { + if (!getOcsid() + .equals(other.getOcsid())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -2410,78 +2330,78 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasXhat()) { - hash = (37 * hash) + XHAT_FIELD_NUMBER; - hash = (53 * hash) + getXhat().hashCode(); + if (hasOcsid()) { + hash = (37 * hash) + OCSID_FIELD_NUMBER; + hash = (53 * hash) + getOcsid().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -2494,7 +2414,7 @@ public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.ReencryptReply prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.CreateOCSReply prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -2511,31 +2431,33 @@ protected Builder newBuilderForType( } /** *
-     * MessageReencryptReply is the reply if the re-encryption is successful, and
-     * it contains XHat, which is the secret re-encrypted to the ephemeral
-     * key given in AuthReencrypt.
+     * CreateOCSReply is the reply sent by the conode if the OCS has been
+     * setup correctly. It contains the ID of the OCS, which is the binary
+     * representation of the aggregate public key. It also has the Sig, which
+     * is the collective signature of all nodes on the aggregate public key
+     * and the authentication.
      * 
* - * Protobuf type {@code ocs.ReencryptReply} + * Protobuf type {@code ocs.CreateOCSReply} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.ReencryptReply) - ch.epfl.dedis.lib.proto.OCS.ReencryptReplyOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.CreateOCSReply) + ch.epfl.dedis.lib.proto.OCS.CreateOCSReplyOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.ReencryptReply.class, ch.epfl.dedis.lib.proto.OCS.ReencryptReply.Builder.class); + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.class, ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.ReencryptReply.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -2553,7 +2475,7 @@ private void maybeForceBuilderInitialization() { @java.lang.Override public Builder clear() { super.clear(); - xhat_ = com.google.protobuf.ByteString.EMPTY; + ocsid_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); return this; } @@ -2561,17 +2483,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_CreateOCSReply_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.ReencryptReply getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.ReencryptReply.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.ReencryptReply build() { - ch.epfl.dedis.lib.proto.OCS.ReencryptReply result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply build() { + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -2579,14 +2501,14 @@ public ch.epfl.dedis.lib.proto.OCS.ReencryptReply build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.ReencryptReply buildPartial() { - ch.epfl.dedis.lib.proto.OCS.ReencryptReply result = new ch.epfl.dedis.lib.proto.OCS.ReencryptReply(this); + public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply buildPartial() { + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply result = new ch.epfl.dedis.lib.proto.OCS.CreateOCSReply(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { to_bitField0_ |= 0x00000001; } - result.xhat_ = xhat_; + result.ocsid_ = ocsid_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -2626,18 +2548,18 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.ReencryptReply) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.ReencryptReply)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.CreateOCSReply) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.CreateOCSReply)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.ReencryptReply other) { - if (other == ch.epfl.dedis.lib.proto.OCS.ReencryptReply.getDefaultInstance()) return this; - if (other.hasXhat()) { - setXhat(other.getXhat()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.CreateOCSReply other) { + if (other == ch.epfl.dedis.lib.proto.OCS.CreateOCSReply.getDefaultInstance()) return this; + if (other.hasOcsid()) { + setOcsid(other.getOcsid()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -2646,7 +2568,7 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.ReencryptReply other) { @java.lang.Override public final boolean isInitialized() { - if (!hasXhat()) { + if (!hasOcsid()) { return false; } return true; @@ -2657,11 +2579,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.ReencryptReply parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.CreateOCSReply parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.ReencryptReply) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.CreateOCSReply) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -2672,37 +2594,37 @@ public Builder mergeFrom( } private int bitField0_; - private com.google.protobuf.ByteString xhat_ = com.google.protobuf.ByteString.EMPTY; + private com.google.protobuf.ByteString ocsid_ = com.google.protobuf.ByteString.EMPTY; /** - * required bytes xhat = 1; + * required bytes ocsid = 1; */ - public boolean hasXhat() { + public boolean hasOcsid() { return ((bitField0_ & 0x00000001) != 0); } /** - * required bytes xhat = 1; + * required bytes ocsid = 1; */ - public com.google.protobuf.ByteString getXhat() { - return xhat_; + public com.google.protobuf.ByteString getOcsid() { + return ocsid_; } /** - * required bytes xhat = 1; + * required bytes ocsid = 1; */ - public Builder setXhat(com.google.protobuf.ByteString value) { + public Builder setOcsid(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000001; - xhat_ = value; + ocsid_ = value; onChanged(); return this; } /** - * required bytes xhat = 1; + * required bytes ocsid = 1; */ - public Builder clearXhat() { + public Builder clearOcsid() { bitField0_ = (bitField0_ & ~0x00000001); - xhat_ = getDefaultInstance().getXhat(); + ocsid_ = getDefaultInstance().getOcsid(); onChanged(); return this; } @@ -2719,105 +2641,78 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.ReencryptReply) + // @@protoc_insertion_point(builder_scope:ocs.CreateOCSReply) } - // @@protoc_insertion_point(class_scope:ocs.ReencryptReply) - private static final ch.epfl.dedis.lib.proto.OCS.ReencryptReply DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.CreateOCSReply) + private static final ch.epfl.dedis.lib.proto.OCS.CreateOCSReply DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.ReencryptReply(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.CreateOCSReply(); } - public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.CreateOCSReply getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public ReencryptReply parsePartialFrom( + public CreateOCSReply parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new ReencryptReply(input, extensionRegistry); + return new CreateOCSReply(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.ReencryptReply getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.CreateOCSReply getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface ReshareOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.Reshare) + public interface GetProofOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.GetProof) com.google.protobuf.MessageOrBuilder { /** - * required bytes x = 1; - */ - boolean hasX(); - /** - * required bytes x = 1; - */ - com.google.protobuf.ByteString getX(); - - /** - * required .onet.Roster newroster = 2; - */ - boolean hasNewroster(); - /** - * required .onet.Roster newroster = 2; - */ - ch.epfl.dedis.lib.proto.OnetProto.Roster getNewroster(); - /** - * required .onet.Roster newroster = 2; - */ - ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getNewrosterOrBuilder(); - - /** - * required .ocs.AuthReshare auth = 3; - */ - boolean hasAuth(); - /** - * required .ocs.AuthReshare auth = 3; + * required bytes ocsid = 1; */ - ch.epfl.dedis.lib.proto.OCS.AuthReshare getAuth(); + boolean hasOcsid(); /** - * required .ocs.AuthReshare auth = 3; + * required bytes ocsid = 1; */ - ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder getAuthOrBuilder(); + com.google.protobuf.ByteString getOcsid(); } /** *
-   * Reshare is called to ask OCS to change the roster. It needs a valid
-   * authentication before the private keys are re-generated over the new
-   * roster.
+   * GetProof is sent to a node to have him sign his definition of the
+   * given OCS.
    * 
* - * Protobuf type {@code ocs.Reshare} + * Protobuf type {@code ocs.GetProof} */ - public static final class Reshare extends + public static final class GetProof extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.Reshare) - ReshareOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.GetProof) + GetProofOrBuilder { private static final long serialVersionUID = 0L; - // Use Reshare.newBuilder() to construct. - private Reshare(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use GetProof.newBuilder() to construct. + private GetProof(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private Reshare() { - x_ = com.google.protobuf.ByteString.EMPTY; + private GetProof() { + ocsid_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -2825,7 +2720,7 @@ private Reshare() { getUnknownFields() { return this.unknownFields; } - private Reshare( + private GetProof( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -2846,33 +2741,7 @@ private Reshare( break; case 10: { bitField0_ |= 0x00000001; - x_ = input.readBytes(); - break; - } - case 18: { - ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null; - if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = newroster_.toBuilder(); - } - newroster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(newroster_); - newroster_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000002; - break; - } - case 26: { - ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder subBuilder = null; - if (((bitField0_ & 0x00000004) != 0)) { - subBuilder = auth_.toBuilder(); - } - auth_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReshare.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(auth_); - auth_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000004; + ocsid_ = input.readBytes(); break; } default: { @@ -2896,73 +2765,31 @@ private Reshare( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GetProof_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GetProof_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.Reshare.class, ch.epfl.dedis.lib.proto.OCS.Reshare.Builder.class); + ch.epfl.dedis.lib.proto.OCS.GetProof.class, ch.epfl.dedis.lib.proto.OCS.GetProof.Builder.class); } private int bitField0_; - public static final int X_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString x_; + public static final int OCSID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString ocsid_; /** - * required bytes x = 1; + * required bytes ocsid = 1; */ - public boolean hasX() { + public boolean hasOcsid() { return ((bitField0_ & 0x00000001) != 0); } /** - * required bytes x = 1; - */ - public com.google.protobuf.ByteString getX() { - return x_; - } - - public static final int NEWROSTER_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.OnetProto.Roster newroster_; - /** - * required .onet.Roster newroster = 2; - */ - public boolean hasNewroster() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * required .onet.Roster newroster = 2; - */ - public ch.epfl.dedis.lib.proto.OnetProto.Roster getNewroster() { - return newroster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; - } - /** - * required .onet.Roster newroster = 2; - */ - public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getNewrosterOrBuilder() { - return newroster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; - } - - public static final int AUTH_FIELD_NUMBER = 3; - private ch.epfl.dedis.lib.proto.OCS.AuthReshare auth_; - /** - * required .ocs.AuthReshare auth = 3; - */ - public boolean hasAuth() { - return ((bitField0_ & 0x00000004) != 0); - } - /** - * required .ocs.AuthReshare auth = 3; - */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshare getAuth() { - return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; - } - /** - * required .ocs.AuthReshare auth = 3; + * required bytes ocsid = 1; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder getAuthOrBuilder() { - return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; + public com.google.protobuf.ByteString getOcsid() { + return ocsid_; } private byte memoizedIsInitialized = -1; @@ -2972,23 +2799,7 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasX()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasNewroster()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasAuth()) { - memoizedIsInitialized = 0; - return false; - } - if (!getNewroster().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } - if (!getAuth().isInitialized()) { + if (!hasOcsid()) { memoizedIsInitialized = 0; return false; } @@ -3000,13 +2811,7 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, x_); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getNewroster()); - } - if (((bitField0_ & 0x00000004) != 0)) { - output.writeMessage(3, getAuth()); + output.writeBytes(1, ocsid_); } unknownFields.writeTo(output); } @@ -3019,15 +2824,7 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, x_); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getNewroster()); - } - if (((bitField0_ & 0x00000004) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(3, getAuth()); + .computeBytesSize(1, ocsid_); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -3039,25 +2836,15 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Reshare)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.GetProof)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.Reshare other = (ch.epfl.dedis.lib.proto.OCS.Reshare) obj; + ch.epfl.dedis.lib.proto.OCS.GetProof other = (ch.epfl.dedis.lib.proto.OCS.GetProof) obj; - if (hasX() != other.hasX()) return false; - if (hasX()) { - if (!getX() - .equals(other.getX())) return false; - } - if (hasNewroster() != other.hasNewroster()) return false; - if (hasNewroster()) { - if (!getNewroster() - .equals(other.getNewroster())) return false; - } - if (hasAuth() != other.hasAuth()) return false; - if (hasAuth()) { - if (!getAuth() - .equals(other.getAuth())) return false; + if (hasOcsid() != other.hasOcsid()) return false; + if (hasOcsid()) { + if (!getOcsid() + .equals(other.getOcsid())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -3070,86 +2857,78 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasX()) { - hash = (37 * hash) + X_FIELD_NUMBER; - hash = (53 * hash) + getX().hashCode(); - } - if (hasNewroster()) { - hash = (37 * hash) + NEWROSTER_FIELD_NUMBER; - hash = (53 * hash) + getNewroster().hashCode(); - } - if (hasAuth()) { - hash = (37 * hash) + AUTH_FIELD_NUMBER; - hash = (53 * hash) + getAuth().hashCode(); + if (hasOcsid()) { + hash = (37 * hash) + OCSID_FIELD_NUMBER; + hash = (53 * hash) + getOcsid().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.GetProof parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3162,7 +2941,7 @@ public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Reshare prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.GetProof prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -3179,31 +2958,30 @@ protected Builder newBuilderForType( } /** *
-     * Reshare is called to ask OCS to change the roster. It needs a valid
-     * authentication before the private keys are re-generated over the new
-     * roster.
+     * GetProof is sent to a node to have him sign his definition of the
+     * given OCS.
      * 
* - * Protobuf type {@code ocs.Reshare} + * Protobuf type {@code ocs.GetProof} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.Reshare) - ch.epfl.dedis.lib.proto.OCS.ReshareOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.GetProof) + ch.epfl.dedis.lib.proto.OCS.GetProofOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GetProof_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GetProof_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.Reshare.class, ch.epfl.dedis.lib.proto.OCS.Reshare.Builder.class); + ch.epfl.dedis.lib.proto.OCS.GetProof.class, ch.epfl.dedis.lib.proto.OCS.GetProof.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.Reshare.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.GetProof.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -3216,44 +2994,30 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { - getNewrosterFieldBuilder(); - getAuthFieldBuilder(); } } @java.lang.Override public Builder clear() { super.clear(); - x_ = com.google.protobuf.ByteString.EMPTY; + ocsid_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); - if (newrosterBuilder_ == null) { - newroster_ = null; - } else { - newrosterBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); - if (authBuilder_ == null) { - auth_ = null; - } else { - authBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000004); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GetProof_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Reshare getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.Reshare.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.GetProof getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.GetProof.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Reshare build() { - ch.epfl.dedis.lib.proto.OCS.Reshare result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.GetProof build() { + ch.epfl.dedis.lib.proto.OCS.GetProof result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -3261,30 +3025,14 @@ public ch.epfl.dedis.lib.proto.OCS.Reshare build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Reshare buildPartial() { - ch.epfl.dedis.lib.proto.OCS.Reshare result = new ch.epfl.dedis.lib.proto.OCS.Reshare(this); + public ch.epfl.dedis.lib.proto.OCS.GetProof buildPartial() { + ch.epfl.dedis.lib.proto.OCS.GetProof result = new ch.epfl.dedis.lib.proto.OCS.GetProof(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { to_bitField0_ |= 0x00000001; } - result.x_ = x_; - if (((from_bitField0_ & 0x00000002) != 0)) { - if (newrosterBuilder_ == null) { - result.newroster_ = newroster_; - } else { - result.newroster_ = newrosterBuilder_.build(); - } - to_bitField0_ |= 0x00000002; - } - if (((from_bitField0_ & 0x00000004) != 0)) { - if (authBuilder_ == null) { - result.auth_ = auth_; - } else { - result.auth_ = authBuilder_.build(); - } - to_bitField0_ |= 0x00000004; - } + result.ocsid_ = ocsid_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -3324,24 +3072,18 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.Reshare) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Reshare)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.GetProof) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.GetProof)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Reshare other) { - if (other == ch.epfl.dedis.lib.proto.OCS.Reshare.getDefaultInstance()) return this; - if (other.hasX()) { - setX(other.getX()); - } - if (other.hasNewroster()) { - mergeNewroster(other.getNewroster()); - } - if (other.hasAuth()) { - mergeAuth(other.getAuth()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.GetProof other) { + if (other == ch.epfl.dedis.lib.proto.OCS.GetProof.getDefaultInstance()) return this; + if (other.hasOcsid()) { + setOcsid(other.getOcsid()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -3350,19 +3092,7 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Reshare other) { @java.lang.Override public final boolean isInitialized() { - if (!hasX()) { - return false; - } - if (!hasNewroster()) { - return false; - } - if (!hasAuth()) { - return false; - } - if (!getNewroster().isInitialized()) { - return false; - } - if (!getAuth().isInitialized()) { + if (!hasOcsid()) { return false; } return true; @@ -3373,11 +3103,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.Reshare parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.GetProof parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Reshare) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.GetProof) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -3388,275 +3118,5091 @@ public Builder mergeFrom( } private int bitField0_; - private com.google.protobuf.ByteString x_ = com.google.protobuf.ByteString.EMPTY; + private com.google.protobuf.ByteString ocsid_ = com.google.protobuf.ByteString.EMPTY; /** - * required bytes x = 1; + * required bytes ocsid = 1; */ - public boolean hasX() { + public boolean hasOcsid() { return ((bitField0_ & 0x00000001) != 0); } /** - * required bytes x = 1; + * required bytes ocsid = 1; */ - public com.google.protobuf.ByteString getX() { - return x_; + public com.google.protobuf.ByteString getOcsid() { + return ocsid_; } /** - * required bytes x = 1; + * required bytes ocsid = 1; */ - public Builder setX(com.google.protobuf.ByteString value) { + public Builder setOcsid(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000001; - x_ = value; + ocsid_ = value; onChanged(); return this; } /** - * required bytes x = 1; + * required bytes ocsid = 1; */ - public Builder clearX() { + public Builder clearOcsid() { bitField0_ = (bitField0_ & ~0x00000001); - x_ = getDefaultInstance().getX(); + ocsid_ = getDefaultInstance().getOcsid(); onChanged(); return this; } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } - private ch.epfl.dedis.lib.proto.OnetProto.Roster newroster_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> newrosterBuilder_; - /** - * required .onet.Roster newroster = 2; - */ - public boolean hasNewroster() { - return ((bitField0_ & 0x00000002) != 0); + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); } - /** - * required .onet.Roster newroster = 2; - */ - public ch.epfl.dedis.lib.proto.OnetProto.Roster getNewroster() { - if (newrosterBuilder_ == null) { - return newroster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; - } else { - return newrosterBuilder_.getMessage(); - } + + + // @@protoc_insertion_point(builder_scope:ocs.GetProof) + } + + // @@protoc_insertion_point(class_scope:ocs.GetProof) + private static final ch.epfl.dedis.lib.proto.OCS.GetProof DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.GetProof(); + } + + public static ch.epfl.dedis.lib.proto.OCS.GetProof getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public GetProof parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new GetProof(input, extensionRegistry); } - /** - * required .onet.Roster newroster = 2; - */ - public Builder setNewroster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { - if (newrosterBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GetProof getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface GetProofReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.GetProofReply) + com.google.protobuf.MessageOrBuilder { + + /** + * required .ocs.OCSProof proof = 1; + */ + boolean hasProof(); + /** + * required .ocs.OCSProof proof = 1; + */ + ch.epfl.dedis.lib.proto.OCS.OCSProof getProof(); + /** + * required .ocs.OCSProof proof = 1; + */ + ch.epfl.dedis.lib.proto.OCS.OCSProofOrBuilder getProofOrBuilder(); + } + /** + *
+   * GetProofReply contains the additional info that node has on the given
+   * OCS, as well as a signature using the services private key.
+   * 
+ * + * Protobuf type {@code ocs.GetProofReply} + */ + public static final class GetProofReply extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.GetProofReply) + GetProofReplyOrBuilder { + private static final long serialVersionUID = 0L; + // Use GetProofReply.newBuilder() to construct. + private GetProofReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private GetProofReply() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private GetProofReply( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + ch.epfl.dedis.lib.proto.OCS.OCSProof.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = proof_.toBuilder(); + } + proof_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.OCSProof.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(proof_); + proof_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } } - newroster_ = value; - onChanged(); - } else { - newrosterBuilder_.setMessage(value); } - bitField0_ |= 0x00000002; - return this; + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); } - /** - * required .onet.Roster newroster = 2; - */ - public Builder setNewroster( - ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder builderForValue) { - if (newrosterBuilder_ == null) { - newroster_ = builderForValue.build(); - onChanged(); - } else { - newrosterBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000002; - return this; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GetProofReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GetProofReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.GetProofReply.class, ch.epfl.dedis.lib.proto.OCS.GetProofReply.Builder.class); + } + + private int bitField0_; + public static final int PROOF_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OCS.OCSProof proof_; + /** + * required .ocs.OCSProof proof = 1; + */ + public boolean hasProof() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required .ocs.OCSProof proof = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.OCSProof getProof() { + return proof_ == null ? ch.epfl.dedis.lib.proto.OCS.OCSProof.getDefaultInstance() : proof_; + } + /** + * required .ocs.OCSProof proof = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.OCSProofOrBuilder getProofOrBuilder() { + return proof_ == null ? ch.epfl.dedis.lib.proto.OCS.OCSProof.getDefaultInstance() : proof_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasProof()) { + memoizedIsInitialized = 0; + return false; } - /** - * required .onet.Roster newroster = 2; - */ - public Builder mergeNewroster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { - if (newrosterBuilder_ == null) { - if (((bitField0_ & 0x00000002) != 0) && - newroster_ != null && - newroster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) { - newroster_ = - ch.epfl.dedis.lib.proto.OnetProto.Roster.newBuilder(newroster_).mergeFrom(value).buildPartial(); - } else { - newroster_ = value; - } - onChanged(); - } else { - newrosterBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000002; - return this; + if (!getProof().isInitialized()) { + memoizedIsInitialized = 0; + return false; } - /** - * required .onet.Roster newroster = 2; - */ - public Builder clearNewroster() { - if (newrosterBuilder_ == null) { - newroster_ = null; - onChanged(); + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getProof()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getProof()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.GetProofReply)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.GetProofReply other = (ch.epfl.dedis.lib.proto.OCS.GetProofReply) obj; + + if (hasProof() != other.hasProof()) return false; + if (hasProof()) { + if (!getProof() + .equals(other.getProof())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasProof()) { + hash = (37 * hash) + PROOF_FIELD_NUMBER; + hash = (53 * hash) + getProof().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.GetProofReply prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * GetProofReply contains the additional info that node has on the given
+     * OCS, as well as a signature using the services private key.
+     * 
+ * + * Protobuf type {@code ocs.GetProofReply} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.GetProofReply) + ch.epfl.dedis.lib.proto.OCS.GetProofReplyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GetProofReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GetProofReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.GetProofReply.class, ch.epfl.dedis.lib.proto.OCS.GetProofReply.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.GetProofReply.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getProofFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (proofBuilder_ == null) { + proof_ = null; } else { - newrosterBuilder_.clear(); + proofBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_GetProofReply_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GetProofReply getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.GetProofReply.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GetProofReply build() { + ch.epfl.dedis.lib.proto.OCS.GetProofReply result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GetProofReply buildPartial() { + ch.epfl.dedis.lib.proto.OCS.GetProofReply result = new ch.epfl.dedis.lib.proto.OCS.GetProofReply(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + if (proofBuilder_ == null) { + result.proof_ = proof_; + } else { + result.proof_ = proofBuilder_.build(); + } + to_bitField0_ |= 0x00000001; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.GetProofReply) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.GetProofReply)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.GetProofReply other) { + if (other == ch.epfl.dedis.lib.proto.OCS.GetProofReply.getDefaultInstance()) return this; + if (other.hasProof()) { + mergeProof(other.getProof()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasProof()) { + return false; + } + if (!getProof().isInitialized()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.GetProofReply parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.GetProofReply) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private ch.epfl.dedis.lib.proto.OCS.OCSProof proof_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.OCSProof, ch.epfl.dedis.lib.proto.OCS.OCSProof.Builder, ch.epfl.dedis.lib.proto.OCS.OCSProofOrBuilder> proofBuilder_; + /** + * required .ocs.OCSProof proof = 1; + */ + public boolean hasProof() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required .ocs.OCSProof proof = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.OCSProof getProof() { + if (proofBuilder_ == null) { + return proof_ == null ? ch.epfl.dedis.lib.proto.OCS.OCSProof.getDefaultInstance() : proof_; + } else { + return proofBuilder_.getMessage(); + } + } + /** + * required .ocs.OCSProof proof = 1; + */ + public Builder setProof(ch.epfl.dedis.lib.proto.OCS.OCSProof value) { + if (proofBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + proof_ = value; + onChanged(); + } else { + proofBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .ocs.OCSProof proof = 1; + */ + public Builder setProof( + ch.epfl.dedis.lib.proto.OCS.OCSProof.Builder builderForValue) { + if (proofBuilder_ == null) { + proof_ = builderForValue.build(); + onChanged(); + } else { + proofBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .ocs.OCSProof proof = 1; + */ + public Builder mergeProof(ch.epfl.dedis.lib.proto.OCS.OCSProof value) { + if (proofBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + proof_ != null && + proof_ != ch.epfl.dedis.lib.proto.OCS.OCSProof.getDefaultInstance()) { + proof_ = + ch.epfl.dedis.lib.proto.OCS.OCSProof.newBuilder(proof_).mergeFrom(value).buildPartial(); + } else { + proof_ = value; + } + onChanged(); + } else { + proofBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * required .ocs.OCSProof proof = 1; + */ + public Builder clearProof() { + if (proofBuilder_ == null) { + proof_ = null; + onChanged(); + } else { + proofBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * required .ocs.OCSProof proof = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.OCSProof.Builder getProofBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getProofFieldBuilder().getBuilder(); + } + /** + * required .ocs.OCSProof proof = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.OCSProofOrBuilder getProofOrBuilder() { + if (proofBuilder_ != null) { + return proofBuilder_.getMessageOrBuilder(); + } else { + return proof_ == null ? + ch.epfl.dedis.lib.proto.OCS.OCSProof.getDefaultInstance() : proof_; + } + } + /** + * required .ocs.OCSProof proof = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.OCSProof, ch.epfl.dedis.lib.proto.OCS.OCSProof.Builder, ch.epfl.dedis.lib.proto.OCS.OCSProofOrBuilder> + getProofFieldBuilder() { + if (proofBuilder_ == null) { + proofBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.OCSProof, ch.epfl.dedis.lib.proto.OCS.OCSProof.Builder, ch.epfl.dedis.lib.proto.OCS.OCSProofOrBuilder>( + getProof(), + getParentForChildren(), + isClean()); + proof_ = null; + } + return proofBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.GetProofReply) + } + + // @@protoc_insertion_point(class_scope:ocs.GetProofReply) + private static final ch.epfl.dedis.lib.proto.OCS.GetProofReply DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.GetProofReply(); + } + + public static ch.epfl.dedis.lib.proto.OCS.GetProofReply getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public GetProofReply parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new GetProofReply(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.GetProofReply getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ReencryptOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.Reencrypt) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes ocsid = 1; + */ + boolean hasOcsid(); + /** + * required bytes ocsid = 1; + */ + com.google.protobuf.ByteString getOcsid(); + + /** + * required .ocs.AuthReencrypt auth = 2; + */ + boolean hasAuth(); + /** + * required .ocs.AuthReencrypt auth = 2; + */ + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getAuth(); + /** + * required .ocs.AuthReencrypt auth = 2; + */ + ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder getAuthOrBuilder(); + } + /** + *
+   * Reencrypt is sent to the service to request a re-encryption of the
+   * secret given in AuthReencrypt. AuthReencrypt must also contain the proof that the
+   * request is valid, as well as the ephemeral key, to which the secret
+   * will be re-encrypted.
+   * 
+ * + * Protobuf type {@code ocs.Reencrypt} + */ + public static final class Reencrypt extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.Reencrypt) + ReencryptOrBuilder { + private static final long serialVersionUID = 0L; + // Use Reencrypt.newBuilder() to construct. + private Reencrypt(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Reencrypt() { + ocsid_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Reencrypt( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + ocsid_ = input.readBytes(); + break; + } + case 18: { + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = auth_.toBuilder(); + } + auth_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(auth_); + auth_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Reencrypt.class, ch.epfl.dedis.lib.proto.OCS.Reencrypt.Builder.class); + } + + private int bitField0_; + public static final int OCSID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString ocsid_; + /** + * required bytes ocsid = 1; + */ + public boolean hasOcsid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes ocsid = 1; + */ + public com.google.protobuf.ByteString getOcsid() { + return ocsid_; + } + + public static final int AUTH_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.AuthReencrypt auth_; + /** + * required .ocs.AuthReencrypt auth = 2; + */ + public boolean hasAuth() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .ocs.AuthReencrypt auth = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getAuth() { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; + } + /** + * required .ocs.AuthReencrypt auth = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder getAuthOrBuilder() { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasOcsid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasAuth()) { + memoizedIsInitialized = 0; + return false; + } + if (!getAuth().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, ocsid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getAuth()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, ocsid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getAuth()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Reencrypt)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.Reencrypt other = (ch.epfl.dedis.lib.proto.OCS.Reencrypt) obj; + + if (hasOcsid() != other.hasOcsid()) return false; + if (hasOcsid()) { + if (!getOcsid() + .equals(other.getOcsid())) return false; + } + if (hasAuth() != other.hasAuth()) return false; + if (hasAuth()) { + if (!getAuth() + .equals(other.getAuth())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasOcsid()) { + hash = (37 * hash) + OCSID_FIELD_NUMBER; + hash = (53 * hash) + getOcsid().hashCode(); + } + if (hasAuth()) { + hash = (37 * hash) + AUTH_FIELD_NUMBER; + hash = (53 * hash) + getAuth().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Reencrypt prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Reencrypt is sent to the service to request a re-encryption of the
+     * secret given in AuthReencrypt. AuthReencrypt must also contain the proof that the
+     * request is valid, as well as the ephemeral key, to which the secret
+     * will be re-encrypted.
+     * 
+ * + * Protobuf type {@code ocs.Reencrypt} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.Reencrypt) + ch.epfl.dedis.lib.proto.OCS.ReencryptOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Reencrypt.class, ch.epfl.dedis.lib.proto.OCS.Reencrypt.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.Reencrypt.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getAuthFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + ocsid_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + if (authBuilder_ == null) { + auth_ = null; + } else { + authBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reencrypt_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reencrypt getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.Reencrypt.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reencrypt build() { + ch.epfl.dedis.lib.proto.OCS.Reencrypt result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reencrypt buildPartial() { + ch.epfl.dedis.lib.proto.OCS.Reencrypt result = new ch.epfl.dedis.lib.proto.OCS.Reencrypt(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.ocsid_ = ocsid_; + if (((from_bitField0_ & 0x00000002) != 0)) { + if (authBuilder_ == null) { + result.auth_ = auth_; + } else { + result.auth_ = authBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.Reencrypt) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Reencrypt)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Reencrypt other) { + if (other == ch.epfl.dedis.lib.proto.OCS.Reencrypt.getDefaultInstance()) return this; + if (other.hasOcsid()) { + setOcsid(other.getOcsid()); + } + if (other.hasAuth()) { + mergeAuth(other.getAuth()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasOcsid()) { + return false; + } + if (!hasAuth()) { + return false; + } + if (!getAuth().isInitialized()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.Reencrypt parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Reencrypt) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString ocsid_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes ocsid = 1; + */ + public boolean hasOcsid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes ocsid = 1; + */ + public com.google.protobuf.ByteString getOcsid() { + return ocsid_; + } + /** + * required bytes ocsid = 1; + */ + public Builder setOcsid(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + ocsid_ = value; + onChanged(); + return this; + } + /** + * required bytes ocsid = 1; + */ + public Builder clearOcsid() { + bitField0_ = (bitField0_ & ~0x00000001); + ocsid_ = getDefaultInstance().getOcsid(); + onChanged(); + return this; + } + + private ch.epfl.dedis.lib.proto.OCS.AuthReencrypt auth_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder> authBuilder_; + /** + * required .ocs.AuthReencrypt auth = 2; + */ + public boolean hasAuth() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .ocs.AuthReencrypt auth = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getAuth() { + if (authBuilder_ == null) { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; + } else { + return authBuilder_.getMessage(); + } + } + /** + * required .ocs.AuthReencrypt auth = 2; + */ + public Builder setAuth(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt value) { + if (authBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + auth_ = value; + onChanged(); + } else { + authBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.AuthReencrypt auth = 2; + */ + public Builder setAuth( + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder builderForValue) { + if (authBuilder_ == null) { + auth_ = builderForValue.build(); + onChanged(); + } else { + authBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.AuthReencrypt auth = 2; + */ + public Builder mergeAuth(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt value) { + if (authBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + auth_ != null && + auth_ != ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance()) { + auth_ = + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.newBuilder(auth_).mergeFrom(value).buildPartial(); + } else { + auth_ = value; + } + onChanged(); + } else { + authBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .ocs.AuthReencrypt auth = 2; + */ + public Builder clearAuth() { + if (authBuilder_ == null) { + auth_ = null; + onChanged(); + } else { + authBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * required .ocs.AuthReencrypt auth = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder getAuthBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getAuthFieldBuilder().getBuilder(); + } + /** + * required .ocs.AuthReencrypt auth = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder getAuthOrBuilder() { + if (authBuilder_ != null) { + return authBuilder_.getMessageOrBuilder(); + } else { + return auth_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance() : auth_; + } + } + /** + * required .ocs.AuthReencrypt auth = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder> + getAuthFieldBuilder() { + if (authBuilder_ == null) { + authBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder>( + getAuth(), + getParentForChildren(), + isClean()); + auth_ = null; + } + return authBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.Reencrypt) + } + + // @@protoc_insertion_point(class_scope:ocs.Reencrypt) + private static final ch.epfl.dedis.lib.proto.OCS.Reencrypt DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Reencrypt(); + } + + public static ch.epfl.dedis.lib.proto.OCS.Reencrypt getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Reencrypt parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Reencrypt(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reencrypt getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ReencryptReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.ReencryptReply) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes x = 1; + */ + boolean hasX(); + /** + * required bytes x = 1; + */ + com.google.protobuf.ByteString getX(); + + /** + * required bytes xhatenc = 2; + */ + boolean hasXhatenc(); + /** + * required bytes xhatenc = 2; + */ + com.google.protobuf.ByteString getXhatenc(); + + /** + * required bytes c = 3; + */ + boolean hasC(); + /** + * required bytes c = 3; + */ + com.google.protobuf.ByteString getC(); + } + /** + *
+   * MessageReencryptReply is the reply if the re-encryption is successful, and
+   * it contains XHat, which is the secret re-encrypted to the ephemeral
+   * key given in AuthReencrypt.
+   * 
+ * + * Protobuf type {@code ocs.ReencryptReply} + */ + public static final class ReencryptReply extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.ReencryptReply) + ReencryptReplyOrBuilder { + private static final long serialVersionUID = 0L; + // Use ReencryptReply.newBuilder() to construct. + private ReencryptReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private ReencryptReply() { + x_ = com.google.protobuf.ByteString.EMPTY; + xhatenc_ = com.google.protobuf.ByteString.EMPTY; + c_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ReencryptReply( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + x_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + xhatenc_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + c_ = input.readBytes(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.ReencryptReply.class, ch.epfl.dedis.lib.proto.OCS.ReencryptReply.Builder.class); + } + + private int bitField0_; + public static final int X_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString x_; + /** + * required bytes x = 1; + */ + public boolean hasX() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes x = 1; + */ + public com.google.protobuf.ByteString getX() { + return x_; + } + + public static final int XHATENC_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString xhatenc_; + /** + * required bytes xhatenc = 2; + */ + public boolean hasXhatenc() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required bytes xhatenc = 2; + */ + public com.google.protobuf.ByteString getXhatenc() { + return xhatenc_; + } + + public static final int C_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString c_; + /** + * required bytes c = 3; + */ + public boolean hasC() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required bytes c = 3; + */ + public com.google.protobuf.ByteString getC() { + return c_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasX()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasXhatenc()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasC()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, x_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeBytes(2, xhatenc_); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeBytes(3, c_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, x_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, xhatenc_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, c_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.ReencryptReply)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.ReencryptReply other = (ch.epfl.dedis.lib.proto.OCS.ReencryptReply) obj; + + if (hasX() != other.hasX()) return false; + if (hasX()) { + if (!getX() + .equals(other.getX())) return false; + } + if (hasXhatenc() != other.hasXhatenc()) return false; + if (hasXhatenc()) { + if (!getXhatenc() + .equals(other.getXhatenc())) return false; + } + if (hasC() != other.hasC()) return false; + if (hasC()) { + if (!getC() + .equals(other.getC())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasX()) { + hash = (37 * hash) + X_FIELD_NUMBER; + hash = (53 * hash) + getX().hashCode(); + } + if (hasXhatenc()) { + hash = (37 * hash) + XHATENC_FIELD_NUMBER; + hash = (53 * hash) + getXhatenc().hashCode(); + } + if (hasC()) { + hash = (37 * hash) + C_FIELD_NUMBER; + hash = (53 * hash) + getC().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.ReencryptReply prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * MessageReencryptReply is the reply if the re-encryption is successful, and
+     * it contains XHat, which is the secret re-encrypted to the ephemeral
+     * key given in AuthReencrypt.
+     * 
+ * + * Protobuf type {@code ocs.ReencryptReply} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.ReencryptReply) + ch.epfl.dedis.lib.proto.OCS.ReencryptReplyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.ReencryptReply.class, ch.epfl.dedis.lib.proto.OCS.ReencryptReply.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.ReencryptReply.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + x_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + xhatenc_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + c_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReencryptReply_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReencryptReply getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.ReencryptReply.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReencryptReply build() { + ch.epfl.dedis.lib.proto.OCS.ReencryptReply result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReencryptReply buildPartial() { + ch.epfl.dedis.lib.proto.OCS.ReencryptReply result = new ch.epfl.dedis.lib.proto.OCS.ReencryptReply(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.x_ = x_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.xhatenc_ = xhatenc_; + if (((from_bitField0_ & 0x00000004) != 0)) { + to_bitField0_ |= 0x00000004; + } + result.c_ = c_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.ReencryptReply) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.ReencryptReply)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.ReencryptReply other) { + if (other == ch.epfl.dedis.lib.proto.OCS.ReencryptReply.getDefaultInstance()) return this; + if (other.hasX()) { + setX(other.getX()); + } + if (other.hasXhatenc()) { + setXhatenc(other.getXhatenc()); + } + if (other.hasC()) { + setC(other.getC()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasX()) { + return false; + } + if (!hasXhatenc()) { + return false; + } + if (!hasC()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.ReencryptReply parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.ReencryptReply) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString x_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes x = 1; + */ + public boolean hasX() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes x = 1; + */ + public com.google.protobuf.ByteString getX() { + return x_; + } + /** + * required bytes x = 1; + */ + public Builder setX(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + x_ = value; + onChanged(); + return this; + } + /** + * required bytes x = 1; + */ + public Builder clearX() { + bitField0_ = (bitField0_ & ~0x00000001); + x_ = getDefaultInstance().getX(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString xhatenc_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes xhatenc = 2; + */ + public boolean hasXhatenc() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required bytes xhatenc = 2; + */ + public com.google.protobuf.ByteString getXhatenc() { + return xhatenc_; + } + /** + * required bytes xhatenc = 2; + */ + public Builder setXhatenc(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + xhatenc_ = value; + onChanged(); + return this; + } + /** + * required bytes xhatenc = 2; + */ + public Builder clearXhatenc() { + bitField0_ = (bitField0_ & ~0x00000002); + xhatenc_ = getDefaultInstance().getXhatenc(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString c_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes c = 3; + */ + public boolean hasC() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required bytes c = 3; + */ + public com.google.protobuf.ByteString getC() { + return c_; + } + /** + * required bytes c = 3; + */ + public Builder setC(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + c_ = value; + onChanged(); + return this; + } + /** + * required bytes c = 3; + */ + public Builder clearC() { + bitField0_ = (bitField0_ & ~0x00000004); + c_ = getDefaultInstance().getC(); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.ReencryptReply) + } + + // @@protoc_insertion_point(class_scope:ocs.ReencryptReply) + private static final ch.epfl.dedis.lib.proto.OCS.ReencryptReply DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.ReencryptReply(); + } + + public static ch.epfl.dedis.lib.proto.OCS.ReencryptReply getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ReencryptReply parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ReencryptReply(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReencryptReply getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ReshareOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.Reshare) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes ocsid = 1; + */ + boolean hasOcsid(); + /** + * required bytes ocsid = 1; + */ + com.google.protobuf.ByteString getOcsid(); + + /** + * required .onet.Roster newroster = 2; + */ + boolean hasNewroster(); + /** + * required .onet.Roster newroster = 2; + */ + ch.epfl.dedis.lib.proto.OnetProto.Roster getNewroster(); + /** + * required .onet.Roster newroster = 2; + */ + ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getNewrosterOrBuilder(); + + /** + * required .ocs.AuthReshare auth = 3; + */ + boolean hasAuth(); + /** + * required .ocs.AuthReshare auth = 3; + */ + ch.epfl.dedis.lib.proto.OCS.AuthReshare getAuth(); + /** + * required .ocs.AuthReshare auth = 3; + */ + ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder getAuthOrBuilder(); + } + /** + *
+   * Reshare is called to ask OCS to change the roster. It needs a valid
+   * authentication before the private keys are re-distributed over the new
+   * roster.
+   * TODO: should NewRoster be always present in AuthReshare? It will be present
+   * TODO: at least in AuthReshareByzCoin, but might not in other AuthReshares
+   * 
+ * + * Protobuf type {@code ocs.Reshare} + */ + public static final class Reshare extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.Reshare) + ReshareOrBuilder { + private static final long serialVersionUID = 0L; + // Use Reshare.newBuilder() to construct. + private Reshare(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Reshare() { + ocsid_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Reshare( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + ocsid_ = input.readBytes(); + break; + } + case 18: { + ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = newroster_.toBuilder(); + } + newroster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(newroster_); + newroster_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + case 26: { + ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder subBuilder = null; + if (((bitField0_ & 0x00000004) != 0)) { + subBuilder = auth_.toBuilder(); + } + auth_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReshare.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(auth_); + auth_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000004; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Reshare.class, ch.epfl.dedis.lib.proto.OCS.Reshare.Builder.class); + } + + private int bitField0_; + public static final int OCSID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString ocsid_; + /** + * required bytes ocsid = 1; + */ + public boolean hasOcsid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes ocsid = 1; + */ + public com.google.protobuf.ByteString getOcsid() { + return ocsid_; + } + + public static final int NEWROSTER_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OnetProto.Roster newroster_; + /** + * required .onet.Roster newroster = 2; + */ + public boolean hasNewroster() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .onet.Roster newroster = 2; + */ + public ch.epfl.dedis.lib.proto.OnetProto.Roster getNewroster() { + return newroster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; + } + /** + * required .onet.Roster newroster = 2; + */ + public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getNewrosterOrBuilder() { + return newroster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; + } + + public static final int AUTH_FIELD_NUMBER = 3; + private ch.epfl.dedis.lib.proto.OCS.AuthReshare auth_; + /** + * required .ocs.AuthReshare auth = 3; + */ + public boolean hasAuth() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required .ocs.AuthReshare auth = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReshare getAuth() { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; + } + /** + * required .ocs.AuthReshare auth = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder getAuthOrBuilder() { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasOcsid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasNewroster()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasAuth()) { + memoizedIsInitialized = 0; + return false; + } + if (!getNewroster().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getAuth().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, ocsid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getNewroster()); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeMessage(3, getAuth()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, ocsid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getNewroster()); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, getAuth()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Reshare)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.Reshare other = (ch.epfl.dedis.lib.proto.OCS.Reshare) obj; + + if (hasOcsid() != other.hasOcsid()) return false; + if (hasOcsid()) { + if (!getOcsid() + .equals(other.getOcsid())) return false; + } + if (hasNewroster() != other.hasNewroster()) return false; + if (hasNewroster()) { + if (!getNewroster() + .equals(other.getNewroster())) return false; + } + if (hasAuth() != other.hasAuth()) return false; + if (hasAuth()) { + if (!getAuth() + .equals(other.getAuth())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasOcsid()) { + hash = (37 * hash) + OCSID_FIELD_NUMBER; + hash = (53 * hash) + getOcsid().hashCode(); + } + if (hasNewroster()) { + hash = (37 * hash) + NEWROSTER_FIELD_NUMBER; + hash = (53 * hash) + getNewroster().hashCode(); + } + if (hasAuth()) { + hash = (37 * hash) + AUTH_FIELD_NUMBER; + hash = (53 * hash) + getAuth().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Reshare parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Reshare prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Reshare is called to ask OCS to change the roster. It needs a valid
+     * authentication before the private keys are re-distributed over the new
+     * roster.
+     * TODO: should NewRoster be always present in AuthReshare? It will be present
+     * TODO: at least in AuthReshareByzCoin, but might not in other AuthReshares
+     * 
+ * + * Protobuf type {@code ocs.Reshare} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.Reshare) + ch.epfl.dedis.lib.proto.OCS.ReshareOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Reshare.class, ch.epfl.dedis.lib.proto.OCS.Reshare.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.Reshare.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getNewrosterFieldBuilder(); + getAuthFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + ocsid_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + if (newrosterBuilder_ == null) { + newroster_ = null; + } else { + newrosterBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + if (authBuilder_ == null) { + auth_ = null; + } else { + authBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Reshare_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reshare getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.Reshare.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reshare build() { + ch.epfl.dedis.lib.proto.OCS.Reshare result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reshare buildPartial() { + ch.epfl.dedis.lib.proto.OCS.Reshare result = new ch.epfl.dedis.lib.proto.OCS.Reshare(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.ocsid_ = ocsid_; + if (((from_bitField0_ & 0x00000002) != 0)) { + if (newrosterBuilder_ == null) { + result.newroster_ = newroster_; + } else { + result.newroster_ = newrosterBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + if (authBuilder_ == null) { + result.auth_ = auth_; + } else { + result.auth_ = authBuilder_.build(); + } + to_bitField0_ |= 0x00000004; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.Reshare) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Reshare)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Reshare other) { + if (other == ch.epfl.dedis.lib.proto.OCS.Reshare.getDefaultInstance()) return this; + if (other.hasOcsid()) { + setOcsid(other.getOcsid()); + } + if (other.hasNewroster()) { + mergeNewroster(other.getNewroster()); + } + if (other.hasAuth()) { + mergeAuth(other.getAuth()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasOcsid()) { + return false; + } + if (!hasNewroster()) { + return false; + } + if (!hasAuth()) { + return false; + } + if (!getNewroster().isInitialized()) { + return false; + } + if (!getAuth().isInitialized()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.Reshare parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Reshare) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString ocsid_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes ocsid = 1; + */ + public boolean hasOcsid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes ocsid = 1; + */ + public com.google.protobuf.ByteString getOcsid() { + return ocsid_; + } + /** + * required bytes ocsid = 1; + */ + public Builder setOcsid(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + ocsid_ = value; + onChanged(); + return this; + } + /** + * required bytes ocsid = 1; + */ + public Builder clearOcsid() { + bitField0_ = (bitField0_ & ~0x00000001); + ocsid_ = getDefaultInstance().getOcsid(); + onChanged(); + return this; + } + + private ch.epfl.dedis.lib.proto.OnetProto.Roster newroster_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> newrosterBuilder_; + /** + * required .onet.Roster newroster = 2; + */ + public boolean hasNewroster() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .onet.Roster newroster = 2; + */ + public ch.epfl.dedis.lib.proto.OnetProto.Roster getNewroster() { + if (newrosterBuilder_ == null) { + return newroster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; + } else { + return newrosterBuilder_.getMessage(); + } + } + /** + * required .onet.Roster newroster = 2; + */ + public Builder setNewroster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { + if (newrosterBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + newroster_ = value; + onChanged(); + } else { + newrosterBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .onet.Roster newroster = 2; + */ + public Builder setNewroster( + ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder builderForValue) { + if (newrosterBuilder_ == null) { + newroster_ = builderForValue.build(); + onChanged(); + } else { + newrosterBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .onet.Roster newroster = 2; + */ + public Builder mergeNewroster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { + if (newrosterBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + newroster_ != null && + newroster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) { + newroster_ = + ch.epfl.dedis.lib.proto.OnetProto.Roster.newBuilder(newroster_).mergeFrom(value).buildPartial(); + } else { + newroster_ = value; + } + onChanged(); + } else { + newrosterBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * required .onet.Roster newroster = 2; + */ + public Builder clearNewroster() { + if (newrosterBuilder_ == null) { + newroster_ = null; + onChanged(); + } else { + newrosterBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * required .onet.Roster newroster = 2; + */ + public ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder getNewrosterBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getNewrosterFieldBuilder().getBuilder(); + } + /** + * required .onet.Roster newroster = 2; + */ + public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getNewrosterOrBuilder() { + if (newrosterBuilder_ != null) { + return newrosterBuilder_.getMessageOrBuilder(); + } else { + return newroster_ == null ? + ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; + } + } + /** + * required .onet.Roster newroster = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> + getNewrosterFieldBuilder() { + if (newrosterBuilder_ == null) { + newrosterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder>( + getNewroster(), + getParentForChildren(), + isClean()); + newroster_ = null; + } + return newrosterBuilder_; + } + + private ch.epfl.dedis.lib.proto.OCS.AuthReshare auth_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReshare, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder> authBuilder_; + /** + * required .ocs.AuthReshare auth = 3; + */ + public boolean hasAuth() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required .ocs.AuthReshare auth = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReshare getAuth() { + if (authBuilder_ == null) { + return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; + } else { + return authBuilder_.getMessage(); + } + } + /** + * required .ocs.AuthReshare auth = 3; + */ + public Builder setAuth(ch.epfl.dedis.lib.proto.OCS.AuthReshare value) { + if (authBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + auth_ = value; + onChanged(); + } else { + authBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .ocs.AuthReshare auth = 3; + */ + public Builder setAuth( + ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder builderForValue) { + if (authBuilder_ == null) { + auth_ = builderForValue.build(); + onChanged(); + } else { + authBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .ocs.AuthReshare auth = 3; + */ + public Builder mergeAuth(ch.epfl.dedis.lib.proto.OCS.AuthReshare value) { + if (authBuilder_ == null) { + if (((bitField0_ & 0x00000004) != 0) && + auth_ != null && + auth_ != ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance()) { + auth_ = + ch.epfl.dedis.lib.proto.OCS.AuthReshare.newBuilder(auth_).mergeFrom(value).buildPartial(); + } else { + auth_ = value; + } + onChanged(); + } else { + authBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .ocs.AuthReshare auth = 3; + */ + public Builder clearAuth() { + if (authBuilder_ == null) { + auth_ = null; + onChanged(); + } else { + authBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + /** + * required .ocs.AuthReshare auth = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder getAuthBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getAuthFieldBuilder().getBuilder(); + } + /** + * required .ocs.AuthReshare auth = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder getAuthOrBuilder() { + if (authBuilder_ != null) { + return authBuilder_.getMessageOrBuilder(); + } else { + return auth_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; + } + } + /** + * required .ocs.AuthReshare auth = 3; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReshare, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder> + getAuthFieldBuilder() { + if (authBuilder_ == null) { + authBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReshare, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder>( + getAuth(), + getParentForChildren(), + isClean()); + auth_ = null; + } + return authBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.Reshare) + } + + // @@protoc_insertion_point(class_scope:ocs.Reshare) + private static final ch.epfl.dedis.lib.proto.OCS.Reshare DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Reshare(); + } + + public static ch.epfl.dedis.lib.proto.OCS.Reshare getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Reshare parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Reshare(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Reshare getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ReshareReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.ReshareReply) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes sig = 1; + */ + boolean hasSig(); + /** + * required bytes sig = 1; + */ + com.google.protobuf.ByteString getSig(); + } + /** + *
+   * ReshareReply is returned if the resharing has been completed successfully
+   * and contains the collective signature on the message
+   *   sha256( X | NewRoster )
+   * 
+ * + * Protobuf type {@code ocs.ReshareReply} + */ + public static final class ReshareReply extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.ReshareReply) + ReshareReplyOrBuilder { + private static final long serialVersionUID = 0L; + // Use ReshareReply.newBuilder() to construct. + private ReshareReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private ReshareReply() { + sig_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ReshareReply( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + sig_ = input.readBytes(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.ReshareReply.class, ch.epfl.dedis.lib.proto.OCS.ReshareReply.Builder.class); + } + + private int bitField0_; + public static final int SIG_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString sig_; + /** + * required bytes sig = 1; + */ + public boolean hasSig() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes sig = 1; + */ + public com.google.protobuf.ByteString getSig() { + return sig_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasSig()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, sig_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, sig_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.ReshareReply)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.ReshareReply other = (ch.epfl.dedis.lib.proto.OCS.ReshareReply) obj; + + if (hasSig() != other.hasSig()) return false; + if (hasSig()) { + if (!getSig() + .equals(other.getSig())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasSig()) { + hash = (37 * hash) + SIG_FIELD_NUMBER; + hash = (53 * hash) + getSig().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.ReshareReply prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * ReshareReply is returned if the resharing has been completed successfully
+     * and contains the collective signature on the message
+     *   sha256( X | NewRoster )
+     * 
+ * + * Protobuf type {@code ocs.ReshareReply} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.ReshareReply) + ch.epfl.dedis.lib.proto.OCS.ReshareReplyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.ReshareReply.class, ch.epfl.dedis.lib.proto.OCS.ReshareReply.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.ReshareReply.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + sig_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReshareReply getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.ReshareReply.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReshareReply build() { + ch.epfl.dedis.lib.proto.OCS.ReshareReply result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReshareReply buildPartial() { + ch.epfl.dedis.lib.proto.OCS.ReshareReply result = new ch.epfl.dedis.lib.proto.OCS.ReshareReply(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.sig_ = sig_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.ReshareReply) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.ReshareReply)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.ReshareReply other) { + if (other == ch.epfl.dedis.lib.proto.OCS.ReshareReply.getDefaultInstance()) return this; + if (other.hasSig()) { + setSig(other.getSig()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasSig()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.ReshareReply parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.ReshareReply) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString sig_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes sig = 1; + */ + public boolean hasSig() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes sig = 1; + */ + public com.google.protobuf.ByteString getSig() { + return sig_; + } + /** + * required bytes sig = 1; + */ + public Builder setSig(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + sig_ = value; + onChanged(); + return this; + } + /** + * required bytes sig = 1; + */ + public Builder clearSig() { + bitField0_ = (bitField0_ & ~0x00000001); + sig_ = getDefaultInstance().getSig(); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.ReshareReply) + } + + // @@protoc_insertion_point(class_scope:ocs.ReshareReply) + private static final ch.epfl.dedis.lib.proto.OCS.ReshareReply DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.ReshareReply(); + } + + public static ch.epfl.dedis.lib.proto.OCS.ReshareReply getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ReshareReply parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ReshareReply(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.ReshareReply getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface PolicyOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.Policy) + com.google.protobuf.MessageOrBuilder { + + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + boolean hasByzcoin(); + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getByzcoin(); + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder getByzcoinOrBuilder(); + + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + boolean hasX509Cert(); + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getX509Cert(); + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder getX509CertOrBuilder(); + } + /** + *
+   * Policy holds all possible authentication structures. When using it to call
+   * Authorise, only one of the fields must be non-nil.
+   * 
+ * + * Protobuf type {@code ocs.Policy} + */ + public static final class Policy extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.Policy) + PolicyOrBuilder { + private static final long serialVersionUID = 0L; + // Use Policy.newBuilder() to construct. + private Policy(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Policy() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Policy( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = byzcoin_.toBuilder(); + } + byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(byzcoin_); + byzcoin_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000001; + break; + } + case 18: { + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = x509Cert_.toBuilder(); + } + x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(x509Cert_); + x509Cert_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Policy.class, ch.epfl.dedis.lib.proto.OCS.Policy.Builder.class); + } + + private int bitField0_; + public static final int BYZCOIN_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin byzcoin_; + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getByzcoin() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder getByzcoinOrBuilder() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; + } + + public static final int X509CERT_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert x509Cert_; + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getX509Cert() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : x509Cert_; + } + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder getX509CertOrBuilder() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : x509Cert_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasX509Cert()) { + if (!getX509Cert().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getX509Cert()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getByzcoin()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getX509Cert()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Policy)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.Policy other = (ch.epfl.dedis.lib.proto.OCS.Policy) obj; + + if (hasByzcoin() != other.hasByzcoin()) return false; + if (hasByzcoin()) { + if (!getByzcoin() + .equals(other.getByzcoin())) return false; + } + if (hasX509Cert() != other.hasX509Cert()) return false; + if (hasX509Cert()) { + if (!getX509Cert() + .equals(other.getX509Cert())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasByzcoin()) { + hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; + hash = (53 * hash) + getByzcoin().hashCode(); + } + if (hasX509Cert()) { + hash = (37 * hash) + X509CERT_FIELD_NUMBER; + hash = (53 * hash) + getX509Cert().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Policy prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Policy holds all possible authentication structures. When using it to call
+     * Authorise, only one of the fields must be non-nil.
+     * 
+ * + * Protobuf type {@code ocs.Policy} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.Policy) + ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.Policy.class, ch.epfl.dedis.lib.proto.OCS.Policy.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getByzcoinFieldBuilder(); + getX509CertFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + if (x509CertBuilder_ == null) { + x509Cert_ = null; + } else { + x509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Policy getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Policy build() { + ch.epfl.dedis.lib.proto.OCS.Policy result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Policy buildPartial() { + ch.epfl.dedis.lib.proto.OCS.Policy result = new ch.epfl.dedis.lib.proto.OCS.Policy(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + if (byzcoinBuilder_ == null) { + result.byzcoin_ = byzcoin_; + } else { + result.byzcoin_ = byzcoinBuilder_.build(); + } + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + if (x509CertBuilder_ == null) { + result.x509Cert_ = x509Cert_; + } else { + result.x509Cert_ = x509CertBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.Policy) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Policy)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Policy other) { + if (other == ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) return this; + if (other.hasByzcoin()) { + mergeByzcoin(other.getByzcoin()); + } + if (other.hasX509Cert()) { + mergeX509Cert(other.getX509Cert()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + return false; + } + } + if (hasX509Cert()) { + if (!getX509Cert().isInitialized()) { + return false; + } + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.Policy parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Policy) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin byzcoin_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder> byzcoinBuilder_; + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getByzcoin() { + if (byzcoinBuilder_ == null) { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; + } else { + return byzcoinBuilder_.getMessage(); + } + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin value) { + if (byzcoinBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + byzcoin_ = value; + onChanged(); + } else { + byzcoinBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public Builder setByzcoin( + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder builderForValue) { + if (byzcoinBuilder_ == null) { + byzcoin_ = builderForValue.build(); + onChanged(); + } else { + byzcoinBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin value) { + if (byzcoinBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + byzcoin_ != null && + byzcoin_ != ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance()) { + byzcoin_ = + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); + } else { + byzcoin_ = value; + } + onChanged(); + } else { + byzcoinBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public Builder clearByzcoin() { + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + onChanged(); + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder getByzcoinBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getByzcoinFieldBuilder().getBuilder(); + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder getByzcoinOrBuilder() { + if (byzcoinBuilder_ != null) { + return byzcoinBuilder_.getMessageOrBuilder(); + } else { + return byzcoin_ == null ? + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; + } + } + /** + * optional .ocs.PolicyByzCoin byzcoin = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder> + getByzcoinFieldBuilder() { + if (byzcoinBuilder_ == null) { + byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder>( + getByzcoin(), + getParentForChildren(), + isClean()); + byzcoin_ = null; + } + return byzcoinBuilder_; + } + + private ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert x509Cert_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder> x509CertBuilder_; + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getX509Cert() { + if (x509CertBuilder_ == null) { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : x509Cert_; + } else { + return x509CertBuilder_.getMessage(); + } + } + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + public Builder setX509Cert(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert value) { + if (x509CertBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + x509Cert_ = value; + onChanged(); + } else { + x509CertBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + public Builder setX509Cert( + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder builderForValue) { + if (x509CertBuilder_ == null) { + x509Cert_ = builderForValue.build(); + onChanged(); + } else { + x509CertBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert value) { + if (x509CertBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + x509Cert_ != null && + x509Cert_ != ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance()) { + x509Cert_ = + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); + } else { + x509Cert_ = value; + } + onChanged(); + } else { + x509CertBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + public Builder clearX509Cert() { + if (x509CertBuilder_ == null) { + x509Cert_ = null; + onChanged(); + } else { + x509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder getX509CertBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getX509CertFieldBuilder().getBuilder(); + } + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder getX509CertOrBuilder() { + if (x509CertBuilder_ != null) { + return x509CertBuilder_.getMessageOrBuilder(); + } else { + return x509Cert_ == null ? + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : x509Cert_; + } + } + /** + * optional .ocs.PolicyX509Cert x509cert = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder> + getX509CertFieldBuilder() { + if (x509CertBuilder_ == null) { + x509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder>( + getX509Cert(), + getParentForChildren(), + isClean()); + x509Cert_ = null; + } + return x509CertBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:ocs.Policy) + } + + // @@protoc_insertion_point(class_scope:ocs.Policy) + private static final ch.epfl.dedis.lib.proto.OCS.Policy DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Policy(); + } + + public static ch.epfl.dedis.lib.proto.OCS.Policy getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Policy parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Policy(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.Policy getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface PolicyByzCoinOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.PolicyByzCoin) + com.google.protobuf.MessageOrBuilder { + + /** + * required bytes byzcoinid = 1; + */ + boolean hasByzcoinid(); + /** + * required bytes byzcoinid = 1; + */ + com.google.protobuf.ByteString getByzcoinid(); + + /** + * required uint64 ttl = 2; + */ + boolean hasTtl(); + /** + * required uint64 ttl = 2; + */ + long getTtl(); + } + /** + *
+   * PolicyByzCoin holds the information necessary to authenticate a byzcoin request.
+   * In the ByzCoin model, all requests are valid as long as they are stored in the
+   * blockchain with the given ID.
+   * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+   * 
+ * + * Protobuf type {@code ocs.PolicyByzCoin} + */ + public static final class PolicyByzCoin extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:ocs.PolicyByzCoin) + PolicyByzCoinOrBuilder { + private static final long serialVersionUID = 0L; + // Use PolicyByzCoin.newBuilder() to construct. + private PolicyByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private PolicyByzCoin() { + byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private PolicyByzCoin( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + bitField0_ |= 0x00000001; + byzcoinid_ = input.readBytes(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + ttl_ = input.readUInt64(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.class, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder.class); + } + + private int bitField0_; + public static final int BYZCOINID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString byzcoinid_; + /** + * required bytes byzcoinid = 1; + */ + public boolean hasByzcoinid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes byzcoinid = 1; + */ + public com.google.protobuf.ByteString getByzcoinid() { + return byzcoinid_; + } + + public static final int TTL_FIELD_NUMBER = 2; + private long ttl_; + /** + * required uint64 ttl = 2; + */ + public boolean hasTtl() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required uint64 ttl = 2; + */ + public long getTtl() { + return ttl_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasByzcoinid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasTtl()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, byzcoinid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeUInt64(2, ttl_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, byzcoinid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(2, ttl_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin)) { + return super.equals(obj); + } + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin other = (ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin) obj; + + if (hasByzcoinid() != other.hasByzcoinid()) return false; + if (hasByzcoinid()) { + if (!getByzcoinid() + .equals(other.getByzcoinid())) return false; + } + if (hasTtl() != other.hasTtl()) return false; + if (hasTtl()) { + if (getTtl() + != other.getTtl()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasByzcoinid()) { + hash = (37 * hash) + BYZCOINID_FIELD_NUMBER; + hash = (53 * hash) + getByzcoinid().hashCode(); + } + if (hasTtl()) { + hash = (37 * hash) + TTL_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getTtl()); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * PolicyByzCoin holds the information necessary to authenticate a byzcoin request.
+     * In the ByzCoin model, all requests are valid as long as they are stored in the
+     * blockchain with the given ID.
+     * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+     * 
+ * + * Protobuf type {@code ocs.PolicyByzCoin} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.PolicyByzCoin) + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.class, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { } + } + @java.lang.Override + public Builder clear() { + super.clear(); + byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + ttl_ = 0L; bitField0_ = (bitField0_ & ~0x00000002); return this; } - /** - * required .onet.Roster newroster = 2; - */ - public ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder getNewrosterBuilder() { - bitField0_ |= 0x00000002; - onChanged(); - return getNewrosterFieldBuilder().getBuilder(); + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_descriptor; } - /** - * required .onet.Roster newroster = 2; - */ - public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getNewrosterOrBuilder() { - if (newrosterBuilder_ != null) { - return newrosterBuilder_.getMessageOrBuilder(); + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin build() { + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin buildPartial() { + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin result = new ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.byzcoinid_ = byzcoinid_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.ttl_ = ttl_; + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin)other); } else { - return newroster_ == null ? - ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : newroster_; + super.mergeFrom(other); + return this; } } - /** - * required .onet.Roster newroster = 2; - */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> - getNewrosterFieldBuilder() { - if (newrosterBuilder_ == null) { - newrosterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder>( - getNewroster(), - getParentForChildren(), - isClean()); - newroster_ = null; + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin other) { + if (other == ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance()) return this; + if (other.hasByzcoinid()) { + setByzcoinid(other.getByzcoinid()); } - return newrosterBuilder_; + if (other.hasTtl()) { + setTtl(other.getTtl()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; } - private ch.epfl.dedis.lib.proto.OCS.AuthReshare auth_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReshare, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder> authBuilder_; - /** - * required .ocs.AuthReshare auth = 3; - */ - public boolean hasAuth() { - return ((bitField0_ & 0x00000004) != 0); + @java.lang.Override + public final boolean isInitialized() { + if (!hasByzcoinid()) { + return false; + } + if (!hasTtl()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; } + private int bitField0_; + + private com.google.protobuf.ByteString byzcoinid_ = com.google.protobuf.ByteString.EMPTY; /** - * required .ocs.AuthReshare auth = 3; + * required bytes byzcoinid = 1; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshare getAuth() { - if (authBuilder_ == null) { - return auth_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; - } else { - return authBuilder_.getMessage(); - } + public boolean hasByzcoinid() { + return ((bitField0_ & 0x00000001) != 0); } /** - * required .ocs.AuthReshare auth = 3; + * required bytes byzcoinid = 1; */ - public Builder setAuth(ch.epfl.dedis.lib.proto.OCS.AuthReshare value) { - if (authBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - auth_ = value; - onChanged(); - } else { - authBuilder_.setMessage(value); - } - bitField0_ |= 0x00000004; - return this; + public com.google.protobuf.ByteString getByzcoinid() { + return byzcoinid_; } /** - * required .ocs.AuthReshare auth = 3; + * required bytes byzcoinid = 1; */ - public Builder setAuth( - ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder builderForValue) { - if (authBuilder_ == null) { - auth_ = builderForValue.build(); - onChanged(); - } else { - authBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000004; + public Builder setByzcoinid(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + byzcoinid_ = value; + onChanged(); return this; } /** - * required .ocs.AuthReshare auth = 3; + * required bytes byzcoinid = 1; */ - public Builder mergeAuth(ch.epfl.dedis.lib.proto.OCS.AuthReshare value) { - if (authBuilder_ == null) { - if (((bitField0_ & 0x00000004) != 0) && - auth_ != null && - auth_ != ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance()) { - auth_ = - ch.epfl.dedis.lib.proto.OCS.AuthReshare.newBuilder(auth_).mergeFrom(value).buildPartial(); - } else { - auth_ = value; - } - onChanged(); - } else { - authBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000004; + public Builder clearByzcoinid() { + bitField0_ = (bitField0_ & ~0x00000001); + byzcoinid_ = getDefaultInstance().getByzcoinid(); + onChanged(); return this; } + + private long ttl_ ; /** - * required .ocs.AuthReshare auth = 3; + * required uint64 ttl = 2; */ - public Builder clearAuth() { - if (authBuilder_ == null) { - auth_ = null; - onChanged(); - } else { - authBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000004); - return this; + public boolean hasTtl() { + return ((bitField0_ & 0x00000002) != 0); } /** - * required .ocs.AuthReshare auth = 3; + * required uint64 ttl = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder getAuthBuilder() { - bitField0_ |= 0x00000004; - onChanged(); - return getAuthFieldBuilder().getBuilder(); + public long getTtl() { + return ttl_; } /** - * required .ocs.AuthReshare auth = 3; + * required uint64 ttl = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder getAuthOrBuilder() { - if (authBuilder_ != null) { - return authBuilder_.getMessageOrBuilder(); - } else { - return auth_ == null ? - ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance() : auth_; - } + public Builder setTtl(long value) { + bitField0_ |= 0x00000002; + ttl_ = value; + onChanged(); + return this; } /** - * required .ocs.AuthReshare auth = 3; + * required uint64 ttl = 2; */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReshare, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder> - getAuthFieldBuilder() { - if (authBuilder_ == null) { - authBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReshare, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder>( - getAuth(), - getParentForChildren(), - isClean()); - auth_ = null; - } - return authBuilder_; + public Builder clearTtl() { + bitField0_ = (bitField0_ & ~0x00000002); + ttl_ = 0L; + onChanged(); + return this; } @java.lang.Override public final Builder setUnknownFields( @@ -3671,79 +8217,106 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.Reshare) + // @@protoc_insertion_point(builder_scope:ocs.PolicyByzCoin) } - // @@protoc_insertion_point(class_scope:ocs.Reshare) - private static final ch.epfl.dedis.lib.proto.OCS.Reshare DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.PolicyByzCoin) + private static final ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Reshare(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin(); } - public static ch.epfl.dedis.lib.proto.OCS.Reshare getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public Reshare parsePartialFrom( + public PolicyByzCoin parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new Reshare(input, extensionRegistry); + return new PolicyByzCoin(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Reshare getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface ReshareReplyOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.ReshareReply) + public interface PolicyX509CertOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.PolicyX509Cert) com.google.protobuf.MessageOrBuilder { /** - * required bytes sig = 1; + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; */ - boolean hasSig(); + java.util.List getCaList(); /** - * required bytes sig = 1; + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; */ - com.google.protobuf.ByteString getSig(); + int getCaCount(); + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + com.google.protobuf.ByteString getCa(int index); + + /** + * required sint32 threshold = 2; + */ + boolean hasThreshold(); + /** + * required sint32 threshold = 2; + */ + int getThreshold(); } /** *
-   * ReshareReply is returned if the resharing has been completed successfully
-   * and contains the collective signature on the message
-   *   sha256( X | NewRoster )
+   * X509Cert holds the information necessary to authenticate a HyperLedger/Fabric
+   * request. In its simplest form, it is simply the CA that will have to sign the
+   * certificates of the requesters.
+   * The Threshold indicates how many clients must have signed the request before it
+   * is accepted.
    * 
* - * Protobuf type {@code ocs.ReshareReply} + * Protobuf type {@code ocs.PolicyX509Cert} */ - public static final class ReshareReply extends + public static final class PolicyX509Cert extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.ReshareReply) - ReshareReplyOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.PolicyX509Cert) + PolicyX509CertOrBuilder { private static final long serialVersionUID = 0L; - // Use ReshareReply.newBuilder() to construct. - private ReshareReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use PolicyX509Cert.newBuilder() to construct. + private PolicyX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private ReshareReply() { - sig_ = com.google.protobuf.ByteString.EMPTY; + private PolicyX509Cert() { + ca_ = java.util.Collections.emptyList(); } @java.lang.Override @@ -3751,7 +8324,7 @@ private ReshareReply() { getUnknownFields() { return this.unknownFields; } - private ReshareReply( + private PolicyX509Cert( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -3771,8 +8344,16 @@ private ReshareReply( done = true; break; case 10: { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + ca_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + ca_.add(input.readBytes()); + break; + } + case 16: { bitField0_ |= 0x00000001; - sig_ = input.readBytes(); + threshold_ = input.readSInt32(); break; } default: { @@ -3790,37 +8371,74 @@ private ReshareReply( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + ca_ = java.util.Collections.unmodifiableList(ca_); // C + } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_fieldAccessorTable + .ensureFieldAccessorsInitialized( + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.class, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder.class); + } + + private int bitField0_; + public static final int CA_FIELD_NUMBER = 1; + private java.util.List ca_; + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public java.util.List + getCaList() { + return ca_; + } + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public int getCaCount() { + return ca_.size(); } - - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_fieldAccessorTable - .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.ReshareReply.class, ch.epfl.dedis.lib.proto.OCS.ReshareReply.Builder.class); + /** + *
+     * Slice of ASN.1 encoded X509 certificates.
+     * 
+ * + * repeated bytes ca = 1; + */ + public com.google.protobuf.ByteString getCa(int index) { + return ca_.get(index); } - private int bitField0_; - public static final int SIG_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString sig_; + public static final int THRESHOLD_FIELD_NUMBER = 2; + private int threshold_; /** - * required bytes sig = 1; + * required sint32 threshold = 2; */ - public boolean hasSig() { + public boolean hasThreshold() { return ((bitField0_ & 0x00000001) != 0); } /** - * required bytes sig = 1; + * required sint32 threshold = 2; */ - public com.google.protobuf.ByteString getSig() { - return sig_; + public int getThreshold() { + return threshold_; } private byte memoizedIsInitialized = -1; @@ -3830,7 +8448,7 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasSig()) { + if (!hasThreshold()) { memoizedIsInitialized = 0; return false; } @@ -3841,8 +8459,11 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + for (int i = 0; i < ca_.size(); i++) { + output.writeBytes(1, ca_.get(i)); + } if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, sig_); + output.writeSInt32(2, threshold_); } unknownFields.writeTo(output); } @@ -3853,9 +8474,18 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; + { + int dataSize = 0; + for (int i = 0; i < ca_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(ca_.get(i)); + } + size += dataSize; + size += 1 * getCaList().size(); + } if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, sig_); + .computeSInt32Size(2, threshold_); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -3867,15 +8497,17 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.ReshareReply)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.ReshareReply other = (ch.epfl.dedis.lib.proto.OCS.ReshareReply) obj; + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert other = (ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert) obj; - if (hasSig() != other.hasSig()) return false; - if (hasSig()) { - if (!getSig() - .equals(other.getSig())) return false; + if (!getCaList() + .equals(other.getCaList())) return false; + if (hasThreshold() != other.hasThreshold()) return false; + if (hasThreshold()) { + if (getThreshold() + != other.getThreshold()) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -3888,78 +8520,82 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasSig()) { - hash = (37 * hash) + SIG_FIELD_NUMBER; - hash = (53 * hash) + getSig().hashCode(); + if (getCaCount() > 0) { + hash = (37 * hash) + CA_FIELD_NUMBER; + hash = (53 * hash) + getCaList().hashCode(); + } + if (hasThreshold()) { + hash = (37 * hash) + THRESHOLD_FIELD_NUMBER; + hash = (53 * hash) + getThreshold(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3972,7 +8608,7 @@ public static ch.epfl.dedis.lib.proto.OCS.ReshareReply parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.ReshareReply prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -3989,31 +8625,33 @@ protected Builder newBuilderForType( } /** *
-     * ReshareReply is returned if the resharing has been completed successfully
-     * and contains the collective signature on the message
-     *   sha256( X | NewRoster )
+     * X509Cert holds the information necessary to authenticate a HyperLedger/Fabric
+     * request. In its simplest form, it is simply the CA that will have to sign the
+     * certificates of the requesters.
+     * The Threshold indicates how many clients must have signed the request before it
+     * is accepted.
      * 
* - * Protobuf type {@code ocs.ReshareReply} + * Protobuf type {@code ocs.PolicyX509Cert} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.ReshareReply) - ch.epfl.dedis.lib.proto.OCS.ReshareReplyOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.PolicyX509Cert) + ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.ReshareReply.class, ch.epfl.dedis.lib.proto.OCS.ReshareReply.Builder.class); + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.class, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.ReshareReply.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -4031,25 +8669,27 @@ private void maybeForceBuilderInitialization() { @java.lang.Override public Builder clear() { super.clear(); - sig_ = com.google.protobuf.ByteString.EMPTY; + ca_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); + threshold_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_ReshareReply_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.ReshareReply getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.ReshareReply.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.ReshareReply build() { - ch.epfl.dedis.lib.proto.OCS.ReshareReply result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert build() { + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -4057,14 +8697,19 @@ public ch.epfl.dedis.lib.proto.OCS.ReshareReply build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.ReshareReply buildPartial() { - ch.epfl.dedis.lib.proto.OCS.ReshareReply result = new ch.epfl.dedis.lib.proto.OCS.ReshareReply(this); + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert buildPartial() { + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert result = new ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) != 0)) { + if (((bitField0_ & 0x00000001) != 0)) { + ca_ = java.util.Collections.unmodifiableList(ca_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.ca_ = ca_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.threshold_ = threshold_; to_bitField0_ |= 0x00000001; } - result.sig_ = sig_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -4104,83 +8749,191 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.ReshareReply) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.ReshareReply)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.ReshareReply other) { - if (other == ch.epfl.dedis.lib.proto.OCS.ReshareReply.getDefaultInstance()) return this; - if (other.hasSig()) { - setSig(other.getSig()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert other) { + if (other == ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance()) return this; + if (!other.ca_.isEmpty()) { + if (ca_.isEmpty()) { + ca_ = other.ca_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureCaIsMutable(); + ca_.addAll(other.ca_); + } + onChanged(); + } + if (other.hasThreshold()) { + setThreshold(other.getThreshold()); } this.mergeUnknownFields(other.unknownFields); onChanged(); return this; } - - @java.lang.Override - public final boolean isInitialized() { - if (!hasSig()) { - return false; - } - return true; + + @java.lang.Override + public final boolean isInitialized() { + if (!hasThreshold()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.util.List ca_ = java.util.Collections.emptyList(); + private void ensureCaIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + ca_ = new java.util.ArrayList(ca_); + bitField0_ |= 0x00000001; + } + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public java.util.List + getCaList() { + return ((bitField0_ & 0x00000001) != 0) ? + java.util.Collections.unmodifiableList(ca_) : ca_; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public int getCaCount() { + return ca_.size(); + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public com.google.protobuf.ByteString getCa(int index) { + return ca_.get(index); + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder setCa( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCaIsMutable(); + ca_.set(index, value); + onChanged(); + return this; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder addCa(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCaIsMutable(); + ca_.add(value); + onChanged(); + return this; } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.ReshareReply parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.ReshareReply) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder addAllCa( + java.lang.Iterable values) { + ensureCaIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, ca_); + onChanged(); + return this; + } + /** + *
+       * Slice of ASN.1 encoded X509 certificates.
+       * 
+ * + * repeated bytes ca = 1; + */ + public Builder clearCa() { + ca_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); return this; } - private int bitField0_; - private com.google.protobuf.ByteString sig_ = com.google.protobuf.ByteString.EMPTY; + private int threshold_ ; /** - * required bytes sig = 1; + * required sint32 threshold = 2; */ - public boolean hasSig() { - return ((bitField0_ & 0x00000001) != 0); + public boolean hasThreshold() { + return ((bitField0_ & 0x00000002) != 0); } /** - * required bytes sig = 1; + * required sint32 threshold = 2; */ - public com.google.protobuf.ByteString getSig() { - return sig_; + public int getThreshold() { + return threshold_; } /** - * required bytes sig = 1; + * required sint32 threshold = 2; */ - public Builder setSig(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - sig_ = value; + public Builder setThreshold(int value) { + bitField0_ |= 0x00000002; + threshold_ = value; onChanged(); return this; } /** - * required bytes sig = 1; + * required sint32 threshold = 2; */ - public Builder clearSig() { - bitField0_ = (bitField0_ & ~0x00000001); - sig_ = getDefaultInstance().getSig(); + public Builder clearThreshold() { + bitField0_ = (bitField0_ & ~0x00000002); + threshold_ = 0; onChanged(); return this; } @@ -4197,98 +8950,94 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.ReshareReply) + // @@protoc_insertion_point(builder_scope:ocs.PolicyX509Cert) } - // @@protoc_insertion_point(class_scope:ocs.ReshareReply) - private static final ch.epfl.dedis.lib.proto.OCS.ReshareReply DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.PolicyX509Cert) + private static final ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.ReshareReply(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert(); } - public static ch.epfl.dedis.lib.proto.OCS.ReshareReply getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public ReshareReply parsePartialFrom( + public PolicyX509Cert parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new ReshareReply(input, extensionRegistry); + return new PolicyX509Cert(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.ReshareReply getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface PolicyOCSOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.PolicyOCS) + public interface AuthCreateOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthCreate) com.google.protobuf.MessageOrBuilder { /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - boolean hasPolicyreencrypt(); + boolean hasByzcoin(); /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt(); + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin getByzcoin(); /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder(); + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoinOrBuilder getByzcoinOrBuilder(); /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - boolean hasPolicyreshare(); + boolean hasX509Cert(); /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare(); + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert getX509Cert(); /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder(); + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509CertOrBuilder getX509CertOrBuilder(); } /** *
-   * PolicyOCS holds the two policies necessary to define an OCS: how to
-   * authenticate a reencryption request, and how to authenticate a
-   * resharing request.
-   * In the current form, both policies point to the same structure. If at
-   * a later moment a new access control backend is added, it might be that
-   * the policies will differ for this new backend.
+   * AuthCreate prooves that the caller has the right to create a new OCS
+   * instance.
    * 
* - * Protobuf type {@code ocs.PolicyOCS} + * Protobuf type {@code ocs.AuthCreate} */ - public static final class PolicyOCS extends + public static final class AuthCreate extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.PolicyOCS) - PolicyOCSOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthCreate) + AuthCreateOrBuilder { private static final long serialVersionUID = 0L; - // Use PolicyOCS.newBuilder() to construct. - private PolicyOCS(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthCreate.newBuilder() to construct. + private AuthCreate(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private PolicyOCS() { + private AuthCreate() { } @java.lang.Override @@ -4296,7 +9045,7 @@ private PolicyOCS() { getUnknownFields() { return this.unknownFields; } - private PolicyOCS( + private AuthCreate( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -4316,27 +9065,27 @@ private PolicyOCS( done = true; break; case 10: { - ch.epfl.dedis.lib.proto.OCS.Policy.Builder subBuilder = null; + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.Builder subBuilder = null; if (((bitField0_ & 0x00000001) != 0)) { - subBuilder = policyreencrypt_.toBuilder(); + subBuilder = byzcoin_.toBuilder(); } - policyreencrypt_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Policy.parser(), extensionRegistry); + byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.parser(), extensionRegistry); if (subBuilder != null) { - subBuilder.mergeFrom(policyreencrypt_); - policyreencrypt_ = subBuilder.buildPartial(); + subBuilder.mergeFrom(byzcoin_); + byzcoin_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000001; break; } case 18: { - ch.epfl.dedis.lib.proto.OCS.Policy.Builder subBuilder = null; + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.Builder subBuilder = null; if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = policyreshare_.toBuilder(); + subBuilder = x509Cert_.toBuilder(); } - policyreshare_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Policy.parser(), extensionRegistry); + x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.parser(), extensionRegistry); if (subBuilder != null) { - subBuilder.mergeFrom(policyreshare_); - policyreshare_ = subBuilder.buildPartial(); + subBuilder.mergeFrom(x509Cert_); + x509Cert_ = subBuilder.buildPartial(); } bitField0_ |= 0x00000002; break; @@ -4362,58 +9111,58 @@ private PolicyOCS( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyOCS_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreate_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyOCS_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreate_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.PolicyOCS.class, ch.epfl.dedis.lib.proto.OCS.PolicyOCS.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthCreate.class, ch.epfl.dedis.lib.proto.OCS.AuthCreate.Builder.class); } private int bitField0_; - public static final int POLICYREENCRYPT_FIELD_NUMBER = 1; - private ch.epfl.dedis.lib.proto.OCS.Policy policyreencrypt_; + public static final int BYZCOIN_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin byzcoin_; /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - public boolean hasPolicyreencrypt() { + public boolean hasByzcoin() { return ((bitField0_ & 0x00000001) != 0); } /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt() { - return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + public ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin getByzcoin() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.getDefaultInstance() : byzcoin_; } /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder() { - return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + public ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoinOrBuilder getByzcoinOrBuilder() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.getDefaultInstance() : byzcoin_; } - public static final int POLICYRESHARE_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.OCS.Policy policyreshare_; + public static final int X509CERT_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert x509Cert_; /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - public boolean hasPolicyreshare() { + public boolean hasX509Cert() { return ((bitField0_ & 0x00000002) != 0); } /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare() { - return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + public ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert getX509Cert() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.getDefaultInstance() : x509Cert_; } /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder() { - return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + public ch.epfl.dedis.lib.proto.OCS.AuthCreateX509CertOrBuilder getX509CertOrBuilder() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.getDefaultInstance() : x509Cert_; } private byte memoizedIsInitialized = -1; @@ -4423,19 +9172,15 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasPolicyreencrypt()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasPolicyreshare()) { + if (!hasByzcoin()) { memoizedIsInitialized = 0; return false; } - if (!getPolicyreencrypt().isInitialized()) { + if (!hasX509Cert()) { memoizedIsInitialized = 0; return false; } - if (!getPolicyreshare().isInitialized()) { + if (!getByzcoin().isInitialized()) { memoizedIsInitialized = 0; return false; } @@ -4447,10 +9192,10 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeMessage(1, getPolicyreencrypt()); + output.writeMessage(1, getByzcoin()); } if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getPolicyreshare()); + output.writeMessage(2, getX509Cert()); } unknownFields.writeTo(output); } @@ -4463,11 +9208,11 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, getPolicyreencrypt()); + .computeMessageSize(1, getByzcoin()); } if (((bitField0_ & 0x00000002) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getPolicyreshare()); + .computeMessageSize(2, getX509Cert()); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -4479,20 +9224,20 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.PolicyOCS)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthCreate)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.PolicyOCS other = (ch.epfl.dedis.lib.proto.OCS.PolicyOCS) obj; + ch.epfl.dedis.lib.proto.OCS.AuthCreate other = (ch.epfl.dedis.lib.proto.OCS.AuthCreate) obj; - if (hasPolicyreencrypt() != other.hasPolicyreencrypt()) return false; - if (hasPolicyreencrypt()) { - if (!getPolicyreencrypt() - .equals(other.getPolicyreencrypt())) return false; + if (hasByzcoin() != other.hasByzcoin()) return false; + if (hasByzcoin()) { + if (!getByzcoin() + .equals(other.getByzcoin())) return false; } - if (hasPolicyreshare() != other.hasPolicyreshare()) return false; - if (hasPolicyreshare()) { - if (!getPolicyreshare() - .equals(other.getPolicyreshare())) return false; + if (hasX509Cert() != other.hasX509Cert()) return false; + if (hasX509Cert()) { + if (!getX509Cert() + .equals(other.getX509Cert())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -4505,82 +9250,82 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasPolicyreencrypt()) { - hash = (37 * hash) + POLICYREENCRYPT_FIELD_NUMBER; - hash = (53 * hash) + getPolicyreencrypt().hashCode(); + if (hasByzcoin()) { + hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; + hash = (53 * hash) + getByzcoin().hashCode(); } - if (hasPolicyreshare()) { - hash = (37 * hash) + POLICYRESHARE_FIELD_NUMBER; - hash = (53 * hash) + getPolicyreshare().hashCode(); + if (hasX509Cert()) { + hash = (37 * hash) + X509CERT_FIELD_NUMBER; + hash = (53 * hash) + getX509Cert().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -4593,7 +9338,7 @@ public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.PolicyOCS prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthCreate prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -4610,34 +9355,30 @@ protected Builder newBuilderForType( } /** *
-     * PolicyOCS holds the two policies necessary to define an OCS: how to
-     * authenticate a reencryption request, and how to authenticate a
-     * resharing request.
-     * In the current form, both policies point to the same structure. If at
-     * a later moment a new access control backend is added, it might be that
-     * the policies will differ for this new backend.
+     * AuthCreate prooves that the caller has the right to create a new OCS
+     * instance.
      * 
* - * Protobuf type {@code ocs.PolicyOCS} + * Protobuf type {@code ocs.AuthCreate} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.PolicyOCS) - ch.epfl.dedis.lib.proto.OCS.PolicyOCSOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthCreate) + ch.epfl.dedis.lib.proto.OCS.AuthCreateOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyOCS_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreate_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyOCS_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreate_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.PolicyOCS.class, ch.epfl.dedis.lib.proto.OCS.PolicyOCS.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthCreate.class, ch.epfl.dedis.lib.proto.OCS.AuthCreate.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.PolicyOCS.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthCreate.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -4650,23 +9391,23 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { - getPolicyreencryptFieldBuilder(); - getPolicyreshareFieldBuilder(); + getByzcoinFieldBuilder(); + getX509CertFieldBuilder(); } } @java.lang.Override public Builder clear() { super.clear(); - if (policyreencryptBuilder_ == null) { - policyreencrypt_ = null; + if (byzcoinBuilder_ == null) { + byzcoin_ = null; } else { - policyreencryptBuilder_.clear(); + byzcoinBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000001); - if (policyreshareBuilder_ == null) { - policyreshare_ = null; + if (x509CertBuilder_ == null) { + x509Cert_ = null; } else { - policyreshareBuilder_.clear(); + x509CertBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000002); return this; @@ -4675,17 +9416,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyOCS_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreate_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyOCS getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.PolicyOCS.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthCreate getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthCreate.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyOCS build() { - ch.epfl.dedis.lib.proto.OCS.PolicyOCS result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthCreate build() { + ch.epfl.dedis.lib.proto.OCS.AuthCreate result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -4693,23 +9434,23 @@ public ch.epfl.dedis.lib.proto.OCS.PolicyOCS build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyOCS buildPartial() { - ch.epfl.dedis.lib.proto.OCS.PolicyOCS result = new ch.epfl.dedis.lib.proto.OCS.PolicyOCS(this); + public ch.epfl.dedis.lib.proto.OCS.AuthCreate buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthCreate result = new ch.epfl.dedis.lib.proto.OCS.AuthCreate(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { - if (policyreencryptBuilder_ == null) { - result.policyreencrypt_ = policyreencrypt_; + if (byzcoinBuilder_ == null) { + result.byzcoin_ = byzcoin_; } else { - result.policyreencrypt_ = policyreencryptBuilder_.build(); + result.byzcoin_ = byzcoinBuilder_.build(); } to_bitField0_ |= 0x00000001; } if (((from_bitField0_ & 0x00000002) != 0)) { - if (policyreshareBuilder_ == null) { - result.policyreshare_ = policyreshare_; + if (x509CertBuilder_ == null) { + result.x509Cert_ = x509Cert_; } else { - result.policyreshare_ = policyreshareBuilder_.build(); + result.x509Cert_ = x509CertBuilder_.build(); } to_bitField0_ |= 0x00000002; } @@ -4752,21 +9493,21 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.PolicyOCS) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.PolicyOCS)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthCreate) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthCreate)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.PolicyOCS other) { - if (other == ch.epfl.dedis.lib.proto.OCS.PolicyOCS.getDefaultInstance()) return this; - if (other.hasPolicyreencrypt()) { - mergePolicyreencrypt(other.getPolicyreencrypt()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthCreate other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthCreate.getDefaultInstance()) return this; + if (other.hasByzcoin()) { + mergeByzcoin(other.getByzcoin()); } - if (other.hasPolicyreshare()) { - mergePolicyreshare(other.getPolicyreshare()); + if (other.hasX509Cert()) { + mergeX509Cert(other.getX509Cert()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -4775,16 +9516,13 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.PolicyOCS other) { @java.lang.Override public final boolean isInitialized() { - if (!hasPolicyreencrypt()) { - return false; - } - if (!hasPolicyreshare()) { + if (!hasByzcoin()) { return false; } - if (!getPolicyreencrypt().isInitialized()) { + if (!hasX509Cert()) { return false; } - if (!getPolicyreshare().isInitialized()) { + if (!getByzcoin().isInitialized()) { return false; } return true; @@ -4795,11 +9533,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.PolicyOCS parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AuthCreate parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.PolicyOCS) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthCreate) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -4810,240 +9548,240 @@ public Builder mergeFrom( } private int bitField0_; - private ch.epfl.dedis.lib.proto.OCS.Policy policyreencrypt_; + private ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin byzcoin_; private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> policyreencryptBuilder_; + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin, ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoinOrBuilder> byzcoinBuilder_; /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - public boolean hasPolicyreencrypt() { + public boolean hasByzcoin() { return ((bitField0_ & 0x00000001) != 0); } /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt() { - if (policyreencryptBuilder_ == null) { - return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + public ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin getByzcoin() { + if (byzcoinBuilder_ == null) { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.getDefaultInstance() : byzcoin_; } else { - return policyreencryptBuilder_.getMessage(); + return byzcoinBuilder_.getMessage(); } } /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - public Builder setPolicyreencrypt(ch.epfl.dedis.lib.proto.OCS.Policy value) { - if (policyreencryptBuilder_ == null) { + public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin value) { + if (byzcoinBuilder_ == null) { if (value == null) { throw new NullPointerException(); } - policyreencrypt_ = value; + byzcoin_ = value; onChanged(); } else { - policyreencryptBuilder_.setMessage(value); + byzcoinBuilder_.setMessage(value); } bitField0_ |= 0x00000001; return this; } /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - public Builder setPolicyreencrypt( - ch.epfl.dedis.lib.proto.OCS.Policy.Builder builderForValue) { - if (policyreencryptBuilder_ == null) { - policyreencrypt_ = builderForValue.build(); + public Builder setByzcoin( + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.Builder builderForValue) { + if (byzcoinBuilder_ == null) { + byzcoin_ = builderForValue.build(); onChanged(); } else { - policyreencryptBuilder_.setMessage(builderForValue.build()); + byzcoinBuilder_.setMessage(builderForValue.build()); } bitField0_ |= 0x00000001; return this; } /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - public Builder mergePolicyreencrypt(ch.epfl.dedis.lib.proto.OCS.Policy value) { - if (policyreencryptBuilder_ == null) { + public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin value) { + if (byzcoinBuilder_ == null) { if (((bitField0_ & 0x00000001) != 0) && - policyreencrypt_ != null && - policyreencrypt_ != ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) { - policyreencrypt_ = - ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder(policyreencrypt_).mergeFrom(value).buildPartial(); + byzcoin_ != null && + byzcoin_ != ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.getDefaultInstance()) { + byzcoin_ = + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); } else { - policyreencrypt_ = value; + byzcoin_ = value; } onChanged(); } else { - policyreencryptBuilder_.mergeFrom(value); + byzcoinBuilder_.mergeFrom(value); } bitField0_ |= 0x00000001; return this; } /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - public Builder clearPolicyreencrypt() { - if (policyreencryptBuilder_ == null) { - policyreencrypt_ = null; + public Builder clearByzcoin() { + if (byzcoinBuilder_ == null) { + byzcoin_ = null; onChanged(); } else { - policyreencryptBuilder_.clear(); + byzcoinBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000001); return this; } /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - public ch.epfl.dedis.lib.proto.OCS.Policy.Builder getPolicyreencryptBuilder() { + public ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.Builder getByzcoinBuilder() { bitField0_ |= 0x00000001; onChanged(); - return getPolicyreencryptFieldBuilder().getBuilder(); + return getByzcoinFieldBuilder().getBuilder(); } /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ - public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder() { - if (policyreencryptBuilder_ != null) { - return policyreencryptBuilder_.getMessageOrBuilder(); + public ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoinOrBuilder getByzcoinOrBuilder() { + if (byzcoinBuilder_ != null) { + return byzcoinBuilder_.getMessageOrBuilder(); } else { - return policyreencrypt_ == null ? - ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + return byzcoin_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.getDefaultInstance() : byzcoin_; } } /** - * required .ocs.Policy policyreencrypt = 1; + * required .ocs.AuthCreateByzcoin byzcoin = 1; */ private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> - getPolicyreencryptFieldBuilder() { - if (policyreencryptBuilder_ == null) { - policyreencryptBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder>( - getPolicyreencrypt(), + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin, ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoinOrBuilder> + getByzcoinFieldBuilder() { + if (byzcoinBuilder_ == null) { + byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin, ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoinOrBuilder>( + getByzcoin(), getParentForChildren(), isClean()); - policyreencrypt_ = null; + byzcoin_ = null; } - return policyreencryptBuilder_; + return byzcoinBuilder_; } - private ch.epfl.dedis.lib.proto.OCS.Policy policyreshare_; + private ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert x509Cert_; private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> policyreshareBuilder_; + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthCreateX509CertOrBuilder> x509CertBuilder_; /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - public boolean hasPolicyreshare() { + public boolean hasX509Cert() { return ((bitField0_ & 0x00000002) != 0); } /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare() { - if (policyreshareBuilder_ == null) { - return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + public ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert getX509Cert() { + if (x509CertBuilder_ == null) { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.getDefaultInstance() : x509Cert_; } else { - return policyreshareBuilder_.getMessage(); + return x509CertBuilder_.getMessage(); } } /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - public Builder setPolicyreshare(ch.epfl.dedis.lib.proto.OCS.Policy value) { - if (policyreshareBuilder_ == null) { + public Builder setX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert value) { + if (x509CertBuilder_ == null) { if (value == null) { throw new NullPointerException(); } - policyreshare_ = value; + x509Cert_ = value; onChanged(); } else { - policyreshareBuilder_.setMessage(value); + x509CertBuilder_.setMessage(value); } bitField0_ |= 0x00000002; return this; } /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - public Builder setPolicyreshare( - ch.epfl.dedis.lib.proto.OCS.Policy.Builder builderForValue) { - if (policyreshareBuilder_ == null) { - policyreshare_ = builderForValue.build(); + public Builder setX509Cert( + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.Builder builderForValue) { + if (x509CertBuilder_ == null) { + x509Cert_ = builderForValue.build(); onChanged(); } else { - policyreshareBuilder_.setMessage(builderForValue.build()); + x509CertBuilder_.setMessage(builderForValue.build()); } bitField0_ |= 0x00000002; return this; } /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - public Builder mergePolicyreshare(ch.epfl.dedis.lib.proto.OCS.Policy value) { - if (policyreshareBuilder_ == null) { + public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert value) { + if (x509CertBuilder_ == null) { if (((bitField0_ & 0x00000002) != 0) && - policyreshare_ != null && - policyreshare_ != ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) { - policyreshare_ = - ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder(policyreshare_).mergeFrom(value).buildPartial(); + x509Cert_ != null && + x509Cert_ != ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.getDefaultInstance()) { + x509Cert_ = + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); } else { - policyreshare_ = value; + x509Cert_ = value; } onChanged(); } else { - policyreshareBuilder_.mergeFrom(value); + x509CertBuilder_.mergeFrom(value); } bitField0_ |= 0x00000002; return this; } /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - public Builder clearPolicyreshare() { - if (policyreshareBuilder_ == null) { - policyreshare_ = null; + public Builder clearX509Cert() { + if (x509CertBuilder_ == null) { + x509Cert_ = null; onChanged(); } else { - policyreshareBuilder_.clear(); + x509CertBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000002); return this; } /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - public ch.epfl.dedis.lib.proto.OCS.Policy.Builder getPolicyreshareBuilder() { + public ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.Builder getX509CertBuilder() { bitField0_ |= 0x00000002; onChanged(); - return getPolicyreshareFieldBuilder().getBuilder(); + return getX509CertFieldBuilder().getBuilder(); } /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ - public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder() { - if (policyreshareBuilder_ != null) { - return policyreshareBuilder_.getMessageOrBuilder(); + public ch.epfl.dedis.lib.proto.OCS.AuthCreateX509CertOrBuilder getX509CertOrBuilder() { + if (x509CertBuilder_ != null) { + return x509CertBuilder_.getMessageOrBuilder(); } else { - return policyreshare_ == null ? - ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + return x509Cert_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.getDefaultInstance() : x509Cert_; } } /** - * required .ocs.Policy policyreshare = 2; + * required .ocs.AuthCreateX509Cert x509cert = 2; */ private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> - getPolicyreshareFieldBuilder() { - if (policyreshareBuilder_ == null) { - policyreshareBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder>( - getPolicyreshare(), + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthCreateX509CertOrBuilder> + getX509CertFieldBuilder() { + if (x509CertBuilder_ == null) { + x509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthCreateX509CertOrBuilder>( + getX509Cert(), getParentForChildren(), isClean()); - policyreshare_ = null; + x509Cert_ = null; } - return policyreshareBuilder_; + return x509CertBuilder_; } @java.lang.Override public final Builder setUnknownFields( @@ -5058,94 +9796,88 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.PolicyOCS) + // @@protoc_insertion_point(builder_scope:ocs.AuthCreate) } - // @@protoc_insertion_point(class_scope:ocs.PolicyOCS) - private static final ch.epfl.dedis.lib.proto.OCS.PolicyOCS DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthCreate) + private static final ch.epfl.dedis.lib.proto.OCS.AuthCreate DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.PolicyOCS(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthCreate(); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyOCS getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthCreate getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public PolicyOCS parsePartialFrom( + public AuthCreate parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new PolicyOCS(input, extensionRegistry); + return new AuthCreate(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyOCS getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthCreate getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface PolicyOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.Policy) + public interface AuthCreateByzcoinOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthCreateByzcoin) com.google.protobuf.MessageOrBuilder { /** - * optional .ocs.PolicyByzCoin byzcoin = 1; - */ - boolean hasByzcoin(); - /** - * optional .ocs.PolicyByzCoin byzcoin = 1; + * required bytes byzcoinid = 1; */ - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getByzcoin(); + boolean hasByzcoinid(); /** - * optional .ocs.PolicyByzCoin byzcoin = 1; + * required bytes byzcoinid = 1; */ - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder getByzcoinOrBuilder(); + com.google.protobuf.ByteString getByzcoinid(); /** - * optional .ocs.PolicyX509Cert authx509cert = 2; - */ - boolean hasAuthx509Cert(); - /** - * optional .ocs.PolicyX509Cert authx509cert = 2; + * required bytes ltsinstance = 2; */ - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getAuthx509Cert(); + boolean hasLtsinstance(); /** - * optional .ocs.PolicyX509Cert authx509cert = 2; + * required bytes ltsinstance = 2; */ - ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder getAuthx509CertOrBuilder(); + com.google.protobuf.ByteString getLtsinstance(); } /** *
-   * Policy holds all possible authentication structures. When using it to call
-   * Authorise, only one of the fields must be non-nil.
+   * AuthCreateByzcoin must give the ByzcoinID and the proof to the LTSInstance
+   * for the creation of a new OCS.
    * 
* - * Protobuf type {@code ocs.Policy} + * Protobuf type {@code ocs.AuthCreateByzcoin} */ - public static final class Policy extends + public static final class AuthCreateByzcoin extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.Policy) - PolicyOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthCreateByzcoin) + AuthCreateByzcoinOrBuilder { private static final long serialVersionUID = 0L; - // Use Policy.newBuilder() to construct. - private Policy(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthCreateByzcoin.newBuilder() to construct. + private AuthCreateByzcoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private Policy() { + private AuthCreateByzcoin() { + byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + ltsinstance_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -5153,7 +9885,7 @@ private Policy() { getUnknownFields() { return this.unknownFields; } - private Policy( + private AuthCreateByzcoin( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -5173,29 +9905,13 @@ private Policy( done = true; break; case 10: { - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder subBuilder = null; - if (((bitField0_ & 0x00000001) != 0)) { - subBuilder = byzcoin_.toBuilder(); - } - byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(byzcoin_); - byzcoin_ = subBuilder.buildPartial(); - } bitField0_ |= 0x00000001; + byzcoinid_ = input.readBytes(); break; } case 18: { - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder subBuilder = null; - if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = authx509Cert_.toBuilder(); - } - authx509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(authx509Cert_); - authx509Cert_ = subBuilder.buildPartial(); - } bitField0_ |= 0x00000002; + ltsinstance_ = input.readBytes(); break; } default: { @@ -5219,58 +9935,46 @@ private Policy( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreateByzcoin_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreateByzcoin_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.Policy.class, ch.epfl.dedis.lib.proto.OCS.Policy.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.class, ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.Builder.class); } private int bitField0_; - public static final int BYZCOIN_FIELD_NUMBER = 1; - private ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin byzcoin_; + public static final int BYZCOINID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString byzcoinid_; /** - * optional .ocs.PolicyByzCoin byzcoin = 1; + * required bytes byzcoinid = 1; */ - public boolean hasByzcoin() { + public boolean hasByzcoinid() { return ((bitField0_ & 0x00000001) != 0); } /** - * optional .ocs.PolicyByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getByzcoin() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; - } - /** - * optional .ocs.PolicyByzCoin byzcoin = 1; + * required bytes byzcoinid = 1; */ - public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder getByzcoinOrBuilder() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; + public com.google.protobuf.ByteString getByzcoinid() { + return byzcoinid_; } - public static final int AUTHX509CERT_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert authx509Cert_; + public static final int LTSINSTANCE_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString ltsinstance_; /** - * optional .ocs.PolicyX509Cert authx509cert = 2; + * required bytes ltsinstance = 2; */ - public boolean hasAuthx509Cert() { + public boolean hasLtsinstance() { return ((bitField0_ & 0x00000002) != 0); } /** - * optional .ocs.PolicyX509Cert authx509cert = 2; - */ - public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getAuthx509Cert() { - return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : authx509Cert_; - } - /** - * optional .ocs.PolicyX509Cert authx509cert = 2; + * required bytes ltsinstance = 2; */ - public ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder getAuthx509CertOrBuilder() { - return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : authx509Cert_; + public com.google.protobuf.ByteString getLtsinstance() { + return ltsinstance_; } private byte memoizedIsInitialized = -1; @@ -5280,17 +9984,13 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } + if (!hasByzcoinid()) { + memoizedIsInitialized = 0; + return false; } - if (hasAuthx509Cert()) { - if (!getAuthx509Cert().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } + if (!hasLtsinstance()) { + memoizedIsInitialized = 0; + return false; } memoizedIsInitialized = 1; return true; @@ -5300,10 +10000,10 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeMessage(1, getByzcoin()); + output.writeBytes(1, byzcoinid_); } if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getAuthx509Cert()); + output.writeBytes(2, ltsinstance_); } unknownFields.writeTo(output); } @@ -5316,11 +10016,11 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, getByzcoin()); + .computeBytesSize(1, byzcoinid_); } if (((bitField0_ & 0x00000002) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getAuthx509Cert()); + .computeBytesSize(2, ltsinstance_); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -5332,20 +10032,20 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.Policy)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.Policy other = (ch.epfl.dedis.lib.proto.OCS.Policy) obj; + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin other = (ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin) obj; - if (hasByzcoin() != other.hasByzcoin()) return false; - if (hasByzcoin()) { - if (!getByzcoin() - .equals(other.getByzcoin())) return false; + if (hasByzcoinid() != other.hasByzcoinid()) return false; + if (hasByzcoinid()) { + if (!getByzcoinid() + .equals(other.getByzcoinid())) return false; } - if (hasAuthx509Cert() != other.hasAuthx509Cert()) return false; - if (hasAuthx509Cert()) { - if (!getAuthx509Cert() - .equals(other.getAuthx509Cert())) return false; + if (hasLtsinstance() != other.hasLtsinstance()) return false; + if (hasLtsinstance()) { + if (!getLtsinstance() + .equals(other.getLtsinstance())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -5358,82 +10058,82 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasByzcoin()) { - hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; - hash = (53 * hash) + getByzcoin().hashCode(); + if (hasByzcoinid()) { + hash = (37 * hash) + BYZCOINID_FIELD_NUMBER; + hash = (53 * hash) + getByzcoinid().hashCode(); } - if (hasAuthx509Cert()) { - hash = (37 * hash) + AUTHX509CERT_FIELD_NUMBER; - hash = (53 * hash) + getAuthx509Cert().hashCode(); + if (hasLtsinstance()) { + hash = (37 * hash) + LTSINSTANCE_FIELD_NUMBER; + hash = (53 * hash) + getLtsinstance().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -5446,7 +10146,7 @@ public static ch.epfl.dedis.lib.proto.OCS.Policy parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.Policy prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -5463,30 +10163,30 @@ protected Builder newBuilderForType( } /** *
-     * Policy holds all possible authentication structures. When using it to call
-     * Authorise, only one of the fields must be non-nil.
+     * AuthCreateByzcoin must give the ByzcoinID and the proof to the LTSInstance
+     * for the creation of a new OCS.
      * 
* - * Protobuf type {@code ocs.Policy} + * Protobuf type {@code ocs.AuthCreateByzcoin} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.Policy) - ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthCreateByzcoin) + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoinOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreateByzcoin_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreateByzcoin_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.Policy.class, ch.epfl.dedis.lib.proto.OCS.Policy.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.class, ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -5499,24 +10199,14 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { - getByzcoinFieldBuilder(); - getAuthx509CertFieldBuilder(); } } @java.lang.Override public Builder clear() { super.clear(); - if (byzcoinBuilder_ == null) { - byzcoin_ = null; - } else { - byzcoinBuilder_.clear(); - } + byzcoinid_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); - if (authx509CertBuilder_ == null) { - authx509Cert_ = null; - } else { - authx509CertBuilder_.clear(); - } + ltsinstance_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000002); return this; } @@ -5524,17 +10214,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_Policy_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreateByzcoin_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Policy getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Policy build() { - ch.epfl.dedis.lib.proto.OCS.Policy result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin build() { + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -5542,26 +10232,18 @@ public ch.epfl.dedis.lib.proto.OCS.Policy build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Policy buildPartial() { - ch.epfl.dedis.lib.proto.OCS.Policy result = new ch.epfl.dedis.lib.proto.OCS.Policy(this); + public ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin result = new ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { - if (byzcoinBuilder_ == null) { - result.byzcoin_ = byzcoin_; - } else { - result.byzcoin_ = byzcoinBuilder_.build(); - } to_bitField0_ |= 0x00000001; } + result.byzcoinid_ = byzcoinid_; if (((from_bitField0_ & 0x00000002) != 0)) { - if (authx509CertBuilder_ == null) { - result.authx509Cert_ = authx509Cert_; - } else { - result.authx509Cert_ = authx509CertBuilder_.build(); - } to_bitField0_ |= 0x00000002; } + result.ltsinstance_ = ltsinstance_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -5601,21 +10283,21 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.Policy) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.Policy)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Policy other) { - if (other == ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) return this; - if (other.hasByzcoin()) { - mergeByzcoin(other.getByzcoin()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin.getDefaultInstance()) return this; + if (other.hasByzcoinid()) { + setByzcoinid(other.getByzcoinid()); } - if (other.hasAuthx509Cert()) { - mergeAuthx509Cert(other.getAuthx509Cert()); + if (other.hasLtsinstance()) { + setLtsinstance(other.getLtsinstance()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -5624,15 +10306,11 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.Policy other) { @java.lang.Override public final boolean isInitialized() { - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - return false; - } + if (!hasByzcoinid()) { + return false; } - if (hasAuthx509Cert()) { - if (!getAuthx509Cert().isInitialized()) { - return false; - } + if (!hasLtsinstance()) { + return false; } return true; } @@ -5642,11 +10320,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.Policy parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.Policy) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -5657,240 +10335,74 @@ public Builder mergeFrom( } private int bitField0_; - private ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin byzcoin_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder> byzcoinBuilder_; + private com.google.protobuf.ByteString byzcoinid_ = com.google.protobuf.ByteString.EMPTY; /** - * optional .ocs.PolicyByzCoin byzcoin = 1; + * required bytes byzcoinid = 1; */ - public boolean hasByzcoin() { + public boolean hasByzcoinid() { return ((bitField0_ & 0x00000001) != 0); } /** - * optional .ocs.PolicyByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getByzcoin() { - if (byzcoinBuilder_ == null) { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; - } else { - return byzcoinBuilder_.getMessage(); - } - } - /** - * optional .ocs.PolicyByzCoin byzcoin = 1; - */ - public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin value) { - if (byzcoinBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - byzcoin_ = value; - onChanged(); - } else { - byzcoinBuilder_.setMessage(value); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .ocs.PolicyByzCoin byzcoin = 1; + * required bytes byzcoinid = 1; */ - public Builder setByzcoin( - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder builderForValue) { - if (byzcoinBuilder_ == null) { - byzcoin_ = builderForValue.build(); - onChanged(); - } else { - byzcoinBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000001; - return this; + public com.google.protobuf.ByteString getByzcoinid() { + return byzcoinid_; } /** - * optional .ocs.PolicyByzCoin byzcoin = 1; + * required bytes byzcoinid = 1; */ - public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin value) { - if (byzcoinBuilder_ == null) { - if (((bitField0_ & 0x00000001) != 0) && - byzcoin_ != null && - byzcoin_ != ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance()) { - byzcoin_ = - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); - } else { - byzcoin_ = value; - } - onChanged(); - } else { - byzcoinBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000001; + public Builder setByzcoinid(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + byzcoinid_ = value; + onChanged(); return this; } /** - * optional .ocs.PolicyByzCoin byzcoin = 1; + * required bytes byzcoinid = 1; */ - public Builder clearByzcoin() { - if (byzcoinBuilder_ == null) { - byzcoin_ = null; - onChanged(); - } else { - byzcoinBuilder_.clear(); - } + public Builder clearByzcoinid() { bitField0_ = (bitField0_ & ~0x00000001); - return this; - } - /** - * optional .ocs.PolicyByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder getByzcoinBuilder() { - bitField0_ |= 0x00000001; + byzcoinid_ = getDefaultInstance().getByzcoinid(); onChanged(); - return getByzcoinFieldBuilder().getBuilder(); - } - /** - * optional .ocs.PolicyByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder getByzcoinOrBuilder() { - if (byzcoinBuilder_ != null) { - return byzcoinBuilder_.getMessageOrBuilder(); - } else { - return byzcoin_ == null ? - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance() : byzcoin_; - } - } - /** - * optional .ocs.PolicyByzCoin byzcoin = 1; - */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder> - getByzcoinFieldBuilder() { - if (byzcoinBuilder_ == null) { - byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder>( - getByzcoin(), - getParentForChildren(), - isClean()); - byzcoin_ = null; - } - return byzcoinBuilder_; + return this; } - private ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert authx509Cert_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder> authx509CertBuilder_; + private com.google.protobuf.ByteString ltsinstance_ = com.google.protobuf.ByteString.EMPTY; /** - * optional .ocs.PolicyX509Cert authx509cert = 2; + * required bytes ltsinstance = 2; */ - public boolean hasAuthx509Cert() { + public boolean hasLtsinstance() { return ((bitField0_ & 0x00000002) != 0); } /** - * optional .ocs.PolicyX509Cert authx509cert = 2; - */ - public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getAuthx509Cert() { - if (authx509CertBuilder_ == null) { - return authx509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : authx509Cert_; - } else { - return authx509CertBuilder_.getMessage(); - } - } - /** - * optional .ocs.PolicyX509Cert authx509cert = 2; - */ - public Builder setAuthx509Cert(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert value) { - if (authx509CertBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - authx509Cert_ = value; - onChanged(); - } else { - authx509CertBuilder_.setMessage(value); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * optional .ocs.PolicyX509Cert authx509cert = 2; + * required bytes ltsinstance = 2; */ - public Builder setAuthx509Cert( - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder builderForValue) { - if (authx509CertBuilder_ == null) { - authx509Cert_ = builderForValue.build(); - onChanged(); - } else { - authx509CertBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000002; - return this; + public com.google.protobuf.ByteString getLtsinstance() { + return ltsinstance_; } /** - * optional .ocs.PolicyX509Cert authx509cert = 2; + * required bytes ltsinstance = 2; */ - public Builder mergeAuthx509Cert(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert value) { - if (authx509CertBuilder_ == null) { - if (((bitField0_ & 0x00000002) != 0) && - authx509Cert_ != null && - authx509Cert_ != ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance()) { - authx509Cert_ = - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.newBuilder(authx509Cert_).mergeFrom(value).buildPartial(); - } else { - authx509Cert_ = value; - } - onChanged(); - } else { - authx509CertBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000002; + public Builder setLtsinstance(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + ltsinstance_ = value; + onChanged(); return this; } /** - * optional .ocs.PolicyX509Cert authx509cert = 2; + * required bytes ltsinstance = 2; */ - public Builder clearAuthx509Cert() { - if (authx509CertBuilder_ == null) { - authx509Cert_ = null; - onChanged(); - } else { - authx509CertBuilder_.clear(); - } + public Builder clearLtsinstance() { bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - /** - * optional .ocs.PolicyX509Cert authx509cert = 2; - */ - public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder getAuthx509CertBuilder() { - bitField0_ |= 0x00000002; + ltsinstance_ = getDefaultInstance().getLtsinstance(); onChanged(); - return getAuthx509CertFieldBuilder().getBuilder(); - } - /** - * optional .ocs.PolicyX509Cert authx509cert = 2; - */ - public ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder getAuthx509CertOrBuilder() { - if (authx509CertBuilder_ != null) { - return authx509CertBuilder_.getMessageOrBuilder(); - } else { - return authx509Cert_ == null ? - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance() : authx509Cert_; - } - } - /** - * optional .ocs.PolicyX509Cert authx509cert = 2; - */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder> - getAuthx509CertFieldBuilder() { - if (authx509CertBuilder_ == null) { - authx509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder>( - getAuthx509Cert(), - getParentForChildren(), - isClean()); - authx509Cert_ = null; - } - return authx509CertBuilder_; + return this; } @java.lang.Override public final Builder setUnknownFields( @@ -5905,89 +10417,82 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.Policy) + // @@protoc_insertion_point(builder_scope:ocs.AuthCreateByzcoin) } - // @@protoc_insertion_point(class_scope:ocs.Policy) - private static final ch.epfl.dedis.lib.proto.OCS.Policy DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthCreateByzcoin) + private static final ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.Policy(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin(); } - public static ch.epfl.dedis.lib.proto.OCS.Policy getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public Policy parsePartialFrom( + public AuthCreateByzcoin parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new Policy(input, extensionRegistry); + return new AuthCreateByzcoin(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.Policy getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthCreateByzcoin getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface PolicyByzCoinOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.PolicyByzCoin) + public interface AuthCreateX509CertOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthCreateX509Cert) com.google.protobuf.MessageOrBuilder { /** - * required bytes byzcoinid = 1; - */ - boolean hasByzcoinid(); - /** - * required bytes byzcoinid = 1; + * repeated bytes certificates = 1; */ - com.google.protobuf.ByteString getByzcoinid(); - + java.util.List getCertificatesList(); /** - * required uint64 ttl = 2; + * repeated bytes certificates = 1; */ - boolean hasTtl(); + int getCertificatesCount(); /** - * required uint64 ttl = 2; + * repeated bytes certificates = 1; */ - long getTtl(); + com.google.protobuf.ByteString getCertificates(int index); } /** *
-   * PolicyByzCoin holds the information necessary to authenticate a byzcoin request.
-   * In the ByzCoin model, all requests are valid as long as they are stored in the
-   * blockchain with the given ID.
-   * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+   * AuthCreateX509Cert must give a threshold number of certificates to proof that
+   * the caller has the right to create a new OCS.
    * 
* - * Protobuf type {@code ocs.PolicyByzCoin} + * Protobuf type {@code ocs.AuthCreateX509Cert} */ - public static final class PolicyByzCoin extends + public static final class AuthCreateX509Cert extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.PolicyByzCoin) - PolicyByzCoinOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthCreateX509Cert) + AuthCreateX509CertOrBuilder { private static final long serialVersionUID = 0L; - // Use PolicyByzCoin.newBuilder() to construct. - private PolicyByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthCreateX509Cert.newBuilder() to construct. + private AuthCreateX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private PolicyByzCoin() { - byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + private AuthCreateX509Cert() { + certificates_ = java.util.Collections.emptyList(); } @java.lang.Override @@ -5995,7 +10500,7 @@ private PolicyByzCoin() { getUnknownFields() { return this.unknownFields; } - private PolicyByzCoin( + private AuthCreateX509Cert( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -6015,13 +10520,11 @@ private PolicyByzCoin( done = true; break; case 10: { - bitField0_ |= 0x00000001; - byzcoinid_ = input.readBytes(); - break; - } - case 16: { - bitField0_ |= 0x00000002; - ttl_ = input.readUInt64(); + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + certificates_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + certificates_.add(input.readBytes()); break; } default: { @@ -6039,52 +10542,46 @@ private PolicyByzCoin( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); // C + } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreateX509Cert_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreateX509Cert_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.class, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.Builder.class); } - private int bitField0_; - public static final int BYZCOINID_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString byzcoinid_; - /** - * required bytes byzcoinid = 1; - */ - public boolean hasByzcoinid() { - return ((bitField0_ & 0x00000001) != 0); - } + public static final int CERTIFICATES_FIELD_NUMBER = 1; + private java.util.List certificates_; /** - * required bytes byzcoinid = 1; + * repeated bytes certificates = 1; */ - public com.google.protobuf.ByteString getByzcoinid() { - return byzcoinid_; + public java.util.List + getCertificatesList() { + return certificates_; } - - public static final int TTL_FIELD_NUMBER = 2; - private long ttl_; /** - * required uint64 ttl = 2; + * repeated bytes certificates = 1; */ - public boolean hasTtl() { - return ((bitField0_ & 0x00000002) != 0); + public int getCertificatesCount() { + return certificates_.size(); } /** - * required uint64 ttl = 2; + * repeated bytes certificates = 1; */ - public long getTtl() { - return ttl_; + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); } private byte memoizedIsInitialized = -1; @@ -6094,14 +10591,6 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasByzcoinid()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasTtl()) { - memoizedIsInitialized = 0; - return false; - } memoizedIsInitialized = 1; return true; } @@ -6109,11 +10598,8 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, byzcoinid_); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeUInt64(2, ttl_); + for (int i = 0; i < certificates_.size(); i++) { + output.writeBytes(1, certificates_.get(i)); } unknownFields.writeTo(output); } @@ -6124,13 +10610,14 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, byzcoinid_); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt64Size(2, ttl_); + { + int dataSize = 0; + for (int i = 0; i < certificates_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(certificates_.get(i)); + } + size += dataSize; + size += 1 * getCertificatesList().size(); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -6142,21 +10629,13 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin other = (ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin) obj; + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert other = (ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert) obj; - if (hasByzcoinid() != other.hasByzcoinid()) return false; - if (hasByzcoinid()) { - if (!getByzcoinid() - .equals(other.getByzcoinid())) return false; - } - if (hasTtl() != other.hasTtl()) return false; - if (hasTtl()) { - if (getTtl() - != other.getTtl()) return false; - } + if (!getCertificatesList() + .equals(other.getCertificatesList())) return false; if (!unknownFields.equals(other.unknownFields)) return false; return true; } @@ -6168,83 +10647,78 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasByzcoinid()) { - hash = (37 * hash) + BYZCOINID_FIELD_NUMBER; - hash = (53 * hash) + getByzcoinid().hashCode(); - } - if (hasTtl()) { - hash = (37 * hash) + TTL_FIELD_NUMBER; - hash = (53 * hash) + com.google.protobuf.Internal.hashLong( - getTtl()); + if (getCertificatesCount() > 0) { + hash = (37 * hash) + CERTIFICATES_FIELD_NUMBER; + hash = (53 * hash) + getCertificatesList().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -6257,7 +10731,7 @@ public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -6274,32 +10748,30 @@ protected Builder newBuilderForType( } /** *
-     * PolicyByzCoin holds the information necessary to authenticate a byzcoin request.
-     * In the ByzCoin model, all requests are valid as long as they are stored in the
-     * blockchain with the given ID.
-     * The TTL is to avoid that too old requests are re-used. If it is 0, it is disabled.
+     * AuthCreateX509Cert must give a threshold number of certificates to proof that
+     * the caller has the right to create a new OCS.
      * 
* - * Protobuf type {@code ocs.PolicyByzCoin} + * Protobuf type {@code ocs.AuthCreateX509Cert} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.PolicyByzCoin) - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoinOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthCreateX509Cert) + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509CertOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreateX509Cert_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreateX509Cert_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.class, ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -6317,27 +10789,25 @@ private void maybeForceBuilderInitialization() { @java.lang.Override public Builder clear() { super.clear(); - byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + certificates_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); - ttl_ = 0L; - bitField0_ = (bitField0_ & ~0x00000002); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthCreateX509Cert_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin build() { - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert build() { + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -6345,19 +10815,14 @@ public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin buildPartial() { - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin result = new ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin(this); + public ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert result = new ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert(this); int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) != 0)) { - to_bitField0_ |= 0x00000001; - } - result.byzcoinid_ = byzcoinid_; - if (((from_bitField0_ & 0x00000002) != 0)) { - result.ttl_ = ttl_; - to_bitField0_ |= 0x00000002; + if (((bitField0_ & 0x00000001) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); + bitField0_ = (bitField0_ & ~0x00000001); } - result.bitField0_ = to_bitField0_; + result.certificates_ = certificates_; onBuilt(); return result; } @@ -6396,21 +10861,25 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin other) { - if (other == ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin.getDefaultInstance()) return this; - if (other.hasByzcoinid()) { - setByzcoinid(other.getByzcoinid()); - } - if (other.hasTtl()) { - setTtl(other.getTtl()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert.getDefaultInstance()) return this; + if (!other.certificates_.isEmpty()) { + if (certificates_.isEmpty()) { + certificates_ = other.certificates_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureCertificatesIsMutable(); + certificates_.addAll(other.certificates_); + } + onChanged(); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -6419,12 +10888,6 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin other) { @java.lang.Override public final boolean isInitialized() { - if (!hasByzcoinid()) { - return false; - } - if (!hasTtl()) { - return false; - } return true; } @@ -6433,11 +10896,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -6448,69 +10911,75 @@ public Builder mergeFrom( } private int bitField0_; - private com.google.protobuf.ByteString byzcoinid_ = com.google.protobuf.ByteString.EMPTY; + private java.util.List certificates_ = java.util.Collections.emptyList(); + private void ensureCertificatesIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + certificates_ = new java.util.ArrayList(certificates_); + bitField0_ |= 0x00000001; + } + } /** - * required bytes byzcoinid = 1; + * repeated bytes certificates = 1; */ - public boolean hasByzcoinid() { - return ((bitField0_ & 0x00000001) != 0); + public java.util.List + getCertificatesList() { + return ((bitField0_ & 0x00000001) != 0) ? + java.util.Collections.unmodifiableList(certificates_) : certificates_; } /** - * required bytes byzcoinid = 1; + * repeated bytes certificates = 1; */ - public com.google.protobuf.ByteString getByzcoinid() { - return byzcoinid_; + public int getCertificatesCount() { + return certificates_.size(); } /** - * required bytes byzcoinid = 1; + * repeated bytes certificates = 1; */ - public Builder setByzcoinid(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - byzcoinid_ = value; - onChanged(); - return this; + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); } /** - * required bytes byzcoinid = 1; + * repeated bytes certificates = 1; */ - public Builder clearByzcoinid() { - bitField0_ = (bitField0_ & ~0x00000001); - byzcoinid_ = getDefaultInstance().getByzcoinid(); + public Builder setCertificates( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCertificatesIsMutable(); + certificates_.set(index, value); onChanged(); return this; } - - private long ttl_ ; - /** - * required uint64 ttl = 2; - */ - public boolean hasTtl() { - return ((bitField0_ & 0x00000002) != 0); - } /** - * required uint64 ttl = 2; + * repeated bytes certificates = 1; */ - public long getTtl() { - return ttl_; + public Builder addCertificates(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCertificatesIsMutable(); + certificates_.add(value); + onChanged(); + return this; } /** - * required uint64 ttl = 2; + * repeated bytes certificates = 1; */ - public Builder setTtl(long value) { - bitField0_ |= 0x00000002; - ttl_ = value; + public Builder addAllCertificates( + java.lang.Iterable values) { + ensureCertificatesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, certificates_); onChanged(); return this; } /** - * required uint64 ttl = 2; + * repeated bytes certificates = 1; */ - public Builder clearTtl() { - bitField0_ = (bitField0_ & ~0x00000002); - ttl_ = 0L; + public Builder clearCertificates() { + certificates_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); onChanged(); return this; } @@ -6527,106 +10996,106 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.PolicyByzCoin) + // @@protoc_insertion_point(builder_scope:ocs.AuthCreateX509Cert) } - // @@protoc_insertion_point(class_scope:ocs.PolicyByzCoin) - private static final ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthCreateX509Cert) + private static final ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert(); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public PolicyByzCoin parsePartialFrom( + public AuthCreateX509Cert parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new PolicyByzCoin(input, extensionRegistry); + return new AuthCreateX509Cert(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyByzCoin getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthCreateX509Cert getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface PolicyX509CertOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.PolicyX509Cert) + public interface AuthReencryptOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReencrypt) com.google.protobuf.MessageOrBuilder { /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; + * required bytes ephemeral = 1; */ - java.util.List getCaList(); + boolean hasEphemeral(); /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; + * required bytes ephemeral = 1; */ - int getCaCount(); + com.google.protobuf.ByteString getEphemeral(); + /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; */ - com.google.protobuf.ByteString getCa(int index); + boolean hasByzcoin(); + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; + */ + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getByzcoin(); + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; + */ + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder getByzcoinOrBuilder(); /** - * required sint32 threshold = 2; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - boolean hasThreshold(); + boolean hasX509Cert(); /** - * required sint32 threshold = 2; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - int getThreshold(); + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getX509Cert(); + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 3; + */ + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder getX509CertOrBuilder(); } /** *
-   * PolicyX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
-   * request. In its simplest form, it is simply the CA that will have to sign the
-   * certificates of the requesters.
-   * The Threshold indicates how many clients must have signed the request before it
-   * is accepted.
+   * AuthReencrypt holds one of the possible authentication proofs for a reencryption request. Each
+   * authentication proof must hold the secret to be reencrypted, the ephemeral key, as well
+   * as the proof itself that the request is valid. For each of the authentication
+   * schemes, this proof will be different.
    * 
* - * Protobuf type {@code ocs.PolicyX509Cert} + * Protobuf type {@code ocs.AuthReencrypt} */ - public static final class PolicyX509Cert extends + public static final class AuthReencrypt extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.PolicyX509Cert) - PolicyX509CertOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthReencrypt) + AuthReencryptOrBuilder { private static final long serialVersionUID = 0L; - // Use PolicyX509Cert.newBuilder() to construct. - private PolicyX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthReencrypt.newBuilder() to construct. + private AuthReencrypt(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private PolicyX509Cert() { - ca_ = java.util.Collections.emptyList(); + private AuthReencrypt() { + ephemeral_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -6634,7 +11103,7 @@ private PolicyX509Cert() { getUnknownFields() { return this.unknownFields; } - private PolicyX509Cert( + private AuthReencrypt( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -6654,16 +11123,34 @@ private PolicyX509Cert( done = true; break; case 10: { - if (!((mutable_bitField0_ & 0x00000001) != 0)) { - ca_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000001; + bitField0_ |= 0x00000001; + ephemeral_ = input.readBytes(); + break; + } + case 18: { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = byzcoin_.toBuilder(); } - ca_.add(input.readBytes()); + byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(byzcoin_); + byzcoin_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; break; } - case 16: { - bitField0_ |= 0x00000001; - threshold_ = input.readSInt32(); + case 26: { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder subBuilder = null; + if (((bitField0_ & 0x00000004) != 0)) { + subBuilder = x509Cert_.toBuilder(); + } + x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(x509Cert_); + x509Cert_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000004; break; } default: { @@ -6681,74 +11168,79 @@ private PolicyX509Cert( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { - if (((mutable_bitField0_ & 0x00000001) != 0)) { - ca_ = java.util.Collections.unmodifiableList(ca_); // C - } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.class, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.class, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder.class); } private int bitField0_; - public static final int CA_FIELD_NUMBER = 1; - private java.util.List ca_; + public static final int EPHEMERAL_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString ephemeral_; /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; + * required bytes ephemeral = 1; */ - public java.util.List - getCaList() { - return ca_; + public boolean hasEphemeral() { + return ((bitField0_ & 0x00000001) != 0); } /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; + * required bytes ephemeral = 1; */ - public int getCaCount() { - return ca_.size(); + public com.google.protobuf.ByteString getEphemeral() { + return ephemeral_; } + + public static final int BYZCOIN_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin byzcoin_; /** - *
-     * Slice of ASN.1 encoded X509 certificates.
-     * 
- * - * repeated bytes ca = 1; + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; */ - public com.google.protobuf.ByteString getCa(int index) { - return ca_.get(index); + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getByzcoin() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder getByzcoinOrBuilder() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; } - public static final int THRESHOLD_FIELD_NUMBER = 2; - private int threshold_; + public static final int X509CERT_FIELD_NUMBER = 3; + private ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert x509Cert_; /** - * required sint32 threshold = 2; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - public boolean hasThreshold() { - return ((bitField0_ & 0x00000001) != 0); + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000004) != 0); } /** - * required sint32 threshold = 2; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - public int getThreshold() { - return threshold_; + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getX509Cert() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder getX509CertOrBuilder() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; } private byte memoizedIsInitialized = -1; @@ -6758,10 +11250,22 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasThreshold()) { + if (!hasEphemeral()) { memoizedIsInitialized = 0; return false; } + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasX509Cert()) { + if (!getX509Cert().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } memoizedIsInitialized = 1; return true; } @@ -6769,11 +11273,14 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - for (int i = 0; i < ca_.size(); i++) { - output.writeBytes(1, ca_.get(i)); - } if (((bitField0_ & 0x00000001) != 0)) { - output.writeSInt32(2, threshold_); + output.writeBytes(1, ephemeral_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getByzcoin()); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeMessage(3, getX509Cert()); } unknownFields.writeTo(output); } @@ -6784,18 +11291,17 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - { - int dataSize = 0; - for (int i = 0; i < ca_.size(); i++) { - dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(ca_.get(i)); - } - size += dataSize; - size += 1 * getCaList().size(); - } if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeSInt32Size(2, threshold_); + .computeBytesSize(1, ephemeral_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getByzcoin()); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, getX509Cert()); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -6807,17 +11313,25 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencrypt)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert other = (ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert) obj; + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt other = (ch.epfl.dedis.lib.proto.OCS.AuthReencrypt) obj; - if (!getCaList() - .equals(other.getCaList())) return false; - if (hasThreshold() != other.hasThreshold()) return false; - if (hasThreshold()) { - if (getThreshold() - != other.getThreshold()) return false; + if (hasEphemeral() != other.hasEphemeral()) return false; + if (hasEphemeral()) { + if (!getEphemeral() + .equals(other.getEphemeral())) return false; + } + if (hasByzcoin() != other.hasByzcoin()) return false; + if (hasByzcoin()) { + if (!getByzcoin() + .equals(other.getByzcoin())) return false; + } + if (hasX509Cert() != other.hasX509Cert()) return false; + if (hasX509Cert()) { + if (!getX509Cert() + .equals(other.getX509Cert())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -6830,82 +11344,86 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (getCaCount() > 0) { - hash = (37 * hash) + CA_FIELD_NUMBER; - hash = (53 * hash) + getCaList().hashCode(); + if (hasEphemeral()) { + hash = (37 * hash) + EPHEMERAL_FIELD_NUMBER; + hash = (53 * hash) + getEphemeral().hashCode(); } - if (hasThreshold()) { - hash = (37 * hash) + THRESHOLD_FIELD_NUMBER; - hash = (53 * hash) + getThreshold(); + if (hasByzcoin()) { + hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; + hash = (53 * hash) + getByzcoin().hashCode(); + } + if (hasX509Cert()) { + hash = (37 * hash) + X509CERT_FIELD_NUMBER; + hash = (53 * hash) + getX509Cert().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -6918,7 +11436,7 @@ public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -6935,33 +11453,32 @@ protected Builder newBuilderForType( } /** *
-     * PolicyX509Cert holds the information necessary to authenticate a HyperLedger/Fabric
-     * request. In its simplest form, it is simply the CA that will have to sign the
-     * certificates of the requesters.
-     * The Threshold indicates how many clients must have signed the request before it
-     * is accepted.
+     * AuthReencrypt holds one of the possible authentication proofs for a reencryption request. Each
+     * authentication proof must hold the secret to be reencrypted, the ephemeral key, as well
+     * as the proof itself that the request is valid. For each of the authentication
+     * schemes, this proof will be different.
      * 
* - * Protobuf type {@code ocs.PolicyX509Cert} + * Protobuf type {@code ocs.AuthReencrypt} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.PolicyX509Cert) - ch.epfl.dedis.lib.proto.OCS.PolicyX509CertOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthReencrypt) + ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.class, ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.class, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -6974,32 +11491,44 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { + getByzcoinFieldBuilder(); + getX509CertFieldBuilder(); } } @java.lang.Override public Builder clear() { super.clear(); - ca_ = java.util.Collections.emptyList(); + ephemeral_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); - threshold_ = 0; + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + } else { + byzcoinBuilder_.clear(); + } bitField0_ = (bitField0_ & ~0x00000002); + if (x509CertBuilder_ == null) { + x509Cert_ = null; + } else { + x509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_PolicyX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert build() { - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt build() { + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -7007,18 +11536,29 @@ public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert buildPartial() { - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert result = new ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert(this); + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt result = new ch.epfl.dedis.lib.proto.OCS.AuthReencrypt(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; - if (((bitField0_ & 0x00000001) != 0)) { - ca_ = java.util.Collections.unmodifiableList(ca_); - bitField0_ = (bitField0_ & ~0x00000001); + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; } - result.ca_ = ca_; + result.ephemeral_ = ephemeral_; if (((from_bitField0_ & 0x00000002) != 0)) { - result.threshold_ = threshold_; - to_bitField0_ |= 0x00000001; + if (byzcoinBuilder_ == null) { + result.byzcoin_ = byzcoin_; + } else { + result.byzcoin_ = byzcoinBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + if (x509CertBuilder_ == null) { + result.x509Cert_ = x509Cert_; + } else { + result.x509Cert_ = x509CertBuilder_.build(); + } + to_bitField0_ |= 0x00000004; } result.bitField0_ = to_bitField0_; onBuilt(); @@ -7059,28 +11599,24 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencrypt) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReencrypt)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert other) { - if (other == ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert.getDefaultInstance()) return this; - if (!other.ca_.isEmpty()) { - if (ca_.isEmpty()) { - ca_ = other.ca_; - bitField0_ = (bitField0_ & ~0x00000001); - } else { - ensureCaIsMutable(); - ca_.addAll(other.ca_); - } - onChanged(); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance()) return this; + if (other.hasEphemeral()) { + setEphemeral(other.getEphemeral()); } - if (other.hasThreshold()) { - setThreshold(other.getThreshold()); + if (other.hasByzcoin()) { + mergeByzcoin(other.getByzcoin()); + } + if (other.hasX509Cert()) { + mergeX509Cert(other.getX509Cert()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -7089,9 +11625,19 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert other) { @java.lang.Override public final boolean isInitialized() { - if (!hasThreshold()) { + if (!hasEphemeral()) { return false; } + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + return false; + } + } + if (hasX509Cert()) { + if (!getX509Cert().isInitialized()) { + return false; + } + } return true; } @@ -7100,11 +11646,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReencrypt) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -7115,137 +11661,275 @@ public Builder mergeFrom( } private int bitField0_; - private java.util.List ca_ = java.util.Collections.emptyList(); - private void ensureCaIsMutable() { - if (!((bitField0_ & 0x00000001) != 0)) { - ca_ = new java.util.ArrayList(ca_); - bitField0_ |= 0x00000001; - } + private com.google.protobuf.ByteString ephemeral_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes ephemeral = 1; + */ + public boolean hasEphemeral() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes ephemeral = 1; + */ + public com.google.protobuf.ByteString getEphemeral() { + return ephemeral_; + } + /** + * required bytes ephemeral = 1; + */ + public Builder setEphemeral(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + ephemeral_ = value; + onChanged(); + return this; + } + /** + * required bytes ephemeral = 1; + */ + public Builder clearEphemeral() { + bitField0_ = (bitField0_ & ~0x00000001); + ephemeral_ = getDefaultInstance().getEphemeral(); + onChanged(); + return this; + } + + private ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin byzcoin_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder> byzcoinBuilder_; + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; + */ + public boolean hasByzcoin() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getByzcoin() { + if (byzcoinBuilder_ == null) { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; + } else { + return byzcoinBuilder_.getMessage(); + } + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; + */ + public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin value) { + if (byzcoinBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + byzcoin_ = value; + onChanged(); + } else { + byzcoinBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; + */ + public Builder setByzcoin( + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder builderForValue) { + if (byzcoinBuilder_ == null) { + byzcoin_ = builderForValue.build(); + onChanged(); + } else { + byzcoinBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; + */ + public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin value) { + if (byzcoinBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + byzcoin_ != null && + byzcoin_ != ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance()) { + byzcoin_ = + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); + } else { + byzcoin_ = value; + } + onChanged(); + } else { + byzcoinBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; + */ + public Builder clearByzcoin() { + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + onChanged(); + } else { + byzcoinBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; } /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; */ - public java.util.List - getCaList() { - return ((bitField0_ & 0x00000001) != 0) ? - java.util.Collections.unmodifiableList(ca_) : ca_; + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder getByzcoinBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getByzcoinFieldBuilder().getBuilder(); } /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; */ - public int getCaCount() { - return ca_.size(); + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder getByzcoinOrBuilder() { + if (byzcoinBuilder_ != null) { + return byzcoinBuilder_.getMessageOrBuilder(); + } else { + return byzcoin_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; + } } /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * optional .ocs.AuthReencryptByzCoin byzcoin = 2; */ - public com.google.protobuf.ByteString getCa(int index) { - return ca_.get(index); + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder> + getByzcoinFieldBuilder() { + if (byzcoinBuilder_ == null) { + byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder>( + getByzcoin(), + getParentForChildren(), + isClean()); + byzcoin_ = null; + } + return byzcoinBuilder_; } + + private ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert x509Cert_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder> x509CertBuilder_; /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - public Builder setCa( - int index, com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureCaIsMutable(); - ca_.set(index, value); - onChanged(); - return this; + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000004) != 0); } /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - public Builder addCa(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureCaIsMutable(); - ca_.add(value); - onChanged(); - return this; + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getX509Cert() { + if (x509CertBuilder_ == null) { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; + } else { + return x509CertBuilder_.getMessage(); + } } /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - public Builder addAllCa( - java.lang.Iterable values) { - ensureCaIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, ca_); - onChanged(); + public Builder setX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert value) { + if (x509CertBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + x509Cert_ = value; + onChanged(); + } else { + x509CertBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; return this; } /** - *
-       * Slice of ASN.1 encoded X509 certificates.
-       * 
- * - * repeated bytes ca = 1; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - public Builder clearCa() { - ca_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000001); - onChanged(); + public Builder setX509Cert( + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder builderForValue) { + if (x509CertBuilder_ == null) { + x509Cert_ = builderForValue.build(); + onChanged(); + } else { + x509CertBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; return this; } - - private int threshold_ ; /** - * required sint32 threshold = 2; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - public boolean hasThreshold() { - return ((bitField0_ & 0x00000002) != 0); + public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert value) { + if (x509CertBuilder_ == null) { + if (((bitField0_ & 0x00000004) != 0) && + x509Cert_ != null && + x509Cert_ != ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance()) { + x509Cert_ = + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); + } else { + x509Cert_ = value; + } + onChanged(); + } else { + x509CertBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + return this; } /** - * required sint32 threshold = 2; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - public int getThreshold() { - return threshold_; + public Builder clearX509Cert() { + if (x509CertBuilder_ == null) { + x509Cert_ = null; + onChanged(); + } else { + x509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; } /** - * required sint32 threshold = 2; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - public Builder setThreshold(int value) { - bitField0_ |= 0x00000002; - threshold_ = value; + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder getX509CertBuilder() { + bitField0_ |= 0x00000004; onChanged(); - return this; + return getX509CertFieldBuilder().getBuilder(); } /** - * required sint32 threshold = 2; + * optional .ocs.AuthReencryptX509Cert x509cert = 3; */ - public Builder clearThreshold() { - bitField0_ = (bitField0_ & ~0x00000002); - threshold_ = 0; - onChanged(); - return this; + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder getX509CertOrBuilder() { + if (x509CertBuilder_ != null) { + return x509CertBuilder_.getMessageOrBuilder(); + } else { + return x509Cert_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; + } + } + /** + * optional .ocs.AuthReencryptX509Cert x509cert = 3; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder> + getX509CertFieldBuilder() { + if (x509CertBuilder_ == null) { + x509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder>( + getX509Cert(), + getParentForChildren(), + isClean()); + x509Cert_ = null; + } + return x509CertBuilder_; } @java.lang.Override public final Builder setUnknownFields( @@ -7260,96 +11944,153 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.PolicyX509Cert) + // @@protoc_insertion_point(builder_scope:ocs.AuthReencrypt) } - // @@protoc_insertion_point(class_scope:ocs.PolicyX509Cert) - private static final ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthReencrypt) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReencrypt DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReencrypt(); } - public static ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public PolicyX509Cert parsePartialFrom( + public AuthReencrypt parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new PolicyX509Cert(input, extensionRegistry); + return new AuthReencrypt(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.PolicyX509Cert getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface AuthReencryptOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.AuthReencrypt) + public interface AuthReencryptByzCoinOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReencryptByzCoin) com.google.protobuf.MessageOrBuilder { /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; + */ + boolean hasWrite(); + /** + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; + */ + com.google.protobuf.ByteString getWrite(); + + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; */ - boolean hasByzcoin(); + boolean hasRead(); + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; + */ + com.google.protobuf.ByteString getRead(); + /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+     * Ephemeral can be non-nil to point to a key to which the data needs to be
+     * re-encrypted to, but then Signature also needs to be non-nil.
+     * 
+ * + * required bytes ephemeral = 3; */ - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getByzcoin(); + boolean hasEphemeral(); /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+     * Ephemeral can be non-nil to point to a key to which the data needs to be
+     * re-encrypted to, but then Signature also needs to be non-nil.
+     * 
+ * + * required bytes ephemeral = 3; */ - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder getByzcoinOrBuilder(); + com.google.protobuf.ByteString getEphemeral(); /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+     * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+     * Read instance to make sure it's a valid reencryption-request.
+     * 
+ * + * optional .darc.Signature signature = 4; */ - boolean hasX509Cert(); + boolean hasSignature(); /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+     * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+     * Read instance to make sure it's a valid reencryption-request.
+     * 
+ * + * optional .darc.Signature signature = 4; */ - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getX509Cert(); + ch.epfl.dedis.lib.proto.DarcProto.Signature getSignature(); /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+     * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+     * Read instance to make sure it's a valid reencryption-request.
+     * 
+ * + * optional .darc.Signature signature = 4; */ - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder getX509CertOrBuilder(); + ch.epfl.dedis.lib.proto.DarcProto.SignatureOrBuilder getSignatureOrBuilder(); } /** *
-   * AuthReencrypt holds one of the possible authentication proofs for a reencryption request. Each
-   * authentication proof must hold the secret to be reencrypted, the ephemeral key, as well
-   * as the proof itself that the request is valid. For each of the authentication
-   * schemes, this proof will be different.
+   * AuthReencryptByzCoin holds the proof of the write instance, holding the secret itself.
+   * The proof of the read instance holds the ephemeral key. Both proofs can be
+   * verified using one of the stored ByzCoinIDs.
    * 
* - * Protobuf type {@code ocs.AuthReencrypt} + * Protobuf type {@code ocs.AuthReencryptByzCoin} */ - public static final class AuthReencrypt extends + public static final class AuthReencryptByzCoin extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.AuthReencrypt) - AuthReencryptOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthReencryptByzCoin) + AuthReencryptByzCoinOrBuilder { private static final long serialVersionUID = 0L; - // Use AuthReencrypt.newBuilder() to construct. - private AuthReencrypt(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthReencryptByzCoin.newBuilder() to construct. + private AuthReencryptByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private AuthReencrypt() { + private AuthReencryptByzCoin() { + write_ = com.google.protobuf.ByteString.EMPTY; + read_ = com.google.protobuf.ByteString.EMPTY; + ephemeral_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -7357,7 +12098,7 @@ private AuthReencrypt() { getUnknownFields() { return this.unknownFields; } - private AuthReencrypt( + private AuthReencryptByzCoin( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -7377,29 +12118,31 @@ private AuthReencrypt( done = true; break; case 10: { - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder subBuilder = null; - if (((bitField0_ & 0x00000001) != 0)) { - subBuilder = byzcoin_.toBuilder(); - } - byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(byzcoin_); - byzcoin_ = subBuilder.buildPartial(); - } bitField0_ |= 0x00000001; + write_ = input.readBytes(); break; } case 18: { - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder subBuilder = null; - if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = x509Cert_.toBuilder(); + bitField0_ |= 0x00000002; + read_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + ephemeral_ = input.readBytes(); + break; + } + case 34: { + ch.epfl.dedis.lib.proto.DarcProto.Signature.Builder subBuilder = null; + if (((bitField0_ & 0x00000008) != 0)) { + subBuilder = signature_.toBuilder(); } - x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.parser(), extensionRegistry); + signature_ = input.readMessage(ch.epfl.dedis.lib.proto.DarcProto.Signature.parser(), extensionRegistry); if (subBuilder != null) { - subBuilder.mergeFrom(x509Cert_); - x509Cert_ = subBuilder.buildPartial(); + subBuilder.mergeFrom(signature_); + signature_ = subBuilder.buildPartial(); } - bitField0_ |= 0x00000002; + bitField0_ |= 0x00000008; break; } default: { @@ -7423,58 +12166,123 @@ private AuthReencrypt( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.class, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder.class); } private int bitField0_; - public static final int BYZCOIN_FIELD_NUMBER = 1; - private ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin byzcoin_; + public static final int WRITE_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString write_; /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; */ - public boolean hasByzcoin() { + public boolean hasWrite() { return ((bitField0_ & 0x00000001) != 0); } /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+     * Write is the proof containing the write request.
+     * 
+ * + * required bytes write = 1; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getByzcoin() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; + public com.google.protobuf.ByteString getWrite() { + return write_; } + + public static final int READ_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString read_; /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder getByzcoinOrBuilder() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; + public boolean hasRead() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+     * Read is the proof that he has been accepted to read the secret.
+     * 
+ * + * required bytes read = 2; + */ + public com.google.protobuf.ByteString getRead() { + return read_; } - public static final int X509CERT_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert x509Cert_; + public static final int EPHEMERAL_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString ephemeral_; /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+     * Ephemeral can be non-nil to point to a key to which the data needs to be
+     * re-encrypted to, but then Signature also needs to be non-nil.
+     * 
+ * + * required bytes ephemeral = 3; */ - public boolean hasX509Cert() { - return ((bitField0_ & 0x00000002) != 0); + public boolean hasEphemeral() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + *
+     * Ephemeral can be non-nil to point to a key to which the data needs to be
+     * re-encrypted to, but then Signature also needs to be non-nil.
+     * 
+ * + * required bytes ephemeral = 3; + */ + public com.google.protobuf.ByteString getEphemeral() { + return ephemeral_; } + + public static final int SIGNATURE_FIELD_NUMBER = 4; + private ch.epfl.dedis.lib.proto.DarcProto.Signature signature_; /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+     * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+     * Read instance to make sure it's a valid reencryption-request.
+     * 
+ * + * optional .darc.Signature signature = 4; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getX509Cert() { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; + public boolean hasSignature() { + return ((bitField0_ & 0x00000008) != 0); } /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+     * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+     * Read instance to make sure it's a valid reencryption-request.
+     * 
+ * + * optional .darc.Signature signature = 4; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder getX509CertOrBuilder() { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; + public ch.epfl.dedis.lib.proto.DarcProto.Signature getSignature() { + return signature_ == null ? ch.epfl.dedis.lib.proto.DarcProto.Signature.getDefaultInstance() : signature_; + } + /** + *
+     * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+     * Read instance to make sure it's a valid reencryption-request.
+     * 
+ * + * optional .darc.Signature signature = 4; + */ + public ch.epfl.dedis.lib.proto.DarcProto.SignatureOrBuilder getSignatureOrBuilder() { + return signature_ == null ? ch.epfl.dedis.lib.proto.DarcProto.Signature.getDefaultInstance() : signature_; } private byte memoizedIsInitialized = -1; @@ -7484,14 +12292,20 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } + if (!hasWrite()) { + memoizedIsInitialized = 0; + return false; } - if (hasX509Cert()) { - if (!getX509Cert().isInitialized()) { + if (!hasRead()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasEphemeral()) { + memoizedIsInitialized = 0; + return false; + } + if (hasSignature()) { + if (!getSignature().isInitialized()) { memoizedIsInitialized = 0; return false; } @@ -7504,10 +12318,16 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeMessage(1, getByzcoin()); + output.writeBytes(1, write_); } if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getX509Cert()); + output.writeBytes(2, read_); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeBytes(3, ephemeral_); + } + if (((bitField0_ & 0x00000008) != 0)) { + output.writeMessage(4, getSignature()); } unknownFields.writeTo(output); } @@ -7520,11 +12340,19 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, getByzcoin()); + .computeBytesSize(1, write_); } if (((bitField0_ & 0x00000002) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getX509Cert()); + .computeBytesSize(2, read_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, ephemeral_); + } + if (((bitField0_ & 0x00000008) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, getSignature()); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -7536,20 +12364,30 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencrypt)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt other = (ch.epfl.dedis.lib.proto.OCS.AuthReencrypt) obj; + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin other = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin) obj; - if (hasByzcoin() != other.hasByzcoin()) return false; - if (hasByzcoin()) { - if (!getByzcoin() - .equals(other.getByzcoin())) return false; + if (hasWrite() != other.hasWrite()) return false; + if (hasWrite()) { + if (!getWrite() + .equals(other.getWrite())) return false; } - if (hasX509Cert() != other.hasX509Cert()) return false; - if (hasX509Cert()) { - if (!getX509Cert() - .equals(other.getX509Cert())) return false; + if (hasRead() != other.hasRead()) return false; + if (hasRead()) { + if (!getRead() + .equals(other.getRead())) return false; + } + if (hasEphemeral() != other.hasEphemeral()) return false; + if (hasEphemeral()) { + if (!getEphemeral() + .equals(other.getEphemeral())) return false; + } + if (hasSignature() != other.hasSignature()) return false; + if (hasSignature()) { + if (!getSignature() + .equals(other.getSignature())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -7562,82 +12400,90 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasByzcoin()) { - hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; - hash = (53 * hash) + getByzcoin().hashCode(); + if (hasWrite()) { + hash = (37 * hash) + WRITE_FIELD_NUMBER; + hash = (53 * hash) + getWrite().hashCode(); } - if (hasX509Cert()) { - hash = (37 * hash) + X509CERT_FIELD_NUMBER; - hash = (53 * hash) + getX509Cert().hashCode(); + if (hasRead()) { + hash = (37 * hash) + READ_FIELD_NUMBER; + hash = (53 * hash) + getRead().hashCode(); + } + if (hasEphemeral()) { + hash = (37 * hash) + EPHEMERAL_FIELD_NUMBER; + hash = (53 * hash) + getEphemeral().hashCode(); + } + if (hasSignature()) { + hash = (37 * hash) + SIGNATURE_FIELD_NUMBER; + hash = (53 * hash) + getSignature().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -7650,7 +12496,7 @@ public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -7667,32 +12513,31 @@ protected Builder newBuilderForType( } /** *
-     * AuthReencrypt holds one of the possible authentication proofs for a reencryption request. Each
-     * authentication proof must hold the secret to be reencrypted, the ephemeral key, as well
-     * as the proof itself that the request is valid. For each of the authentication
-     * schemes, this proof will be different.
+     * AuthReencryptByzCoin holds the proof of the write instance, holding the secret itself.
+     * The proof of the read instance holds the ephemeral key. Both proofs can be
+     * verified using one of the stored ByzCoinIDs.
      * 
* - * Protobuf type {@code ocs.AuthReencrypt} + * Protobuf type {@code ocs.AuthReencryptByzCoin} */ public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.AuthReencrypt) - ch.epfl.dedis.lib.proto.OCS.AuthReencryptOrBuilder { + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:ocs.AuthReencryptByzCoin) + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.class, ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -7705,42 +12550,41 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { - getByzcoinFieldBuilder(); - getX509CertFieldBuilder(); + getSignatureFieldBuilder(); } } @java.lang.Override public Builder clear() { super.clear(); - if (byzcoinBuilder_ == null) { - byzcoin_ = null; - } else { - byzcoinBuilder_.clear(); - } + write_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); - if (x509CertBuilder_ == null) { - x509Cert_ = null; + read_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + ephemeral_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + if (signatureBuilder_ == null) { + signature_ = null; } else { - x509CertBuilder_.clear(); + signatureBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00000002); + bitField0_ = (bitField0_ & ~0x00000008); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencrypt_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt build() { - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin build() { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -7748,25 +12592,29 @@ public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt buildPartial() { - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt result = new ch.epfl.dedis.lib.proto.OCS.AuthReencrypt(this); + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin result = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { - if (byzcoinBuilder_ == null) { - result.byzcoin_ = byzcoin_; - } else { - result.byzcoin_ = byzcoinBuilder_.build(); - } to_bitField0_ |= 0x00000001; } + result.write_ = write_; if (((from_bitField0_ & 0x00000002) != 0)) { - if (x509CertBuilder_ == null) { - result.x509Cert_ = x509Cert_; + to_bitField0_ |= 0x00000002; + } + result.read_ = read_; + if (((from_bitField0_ & 0x00000004) != 0)) { + to_bitField0_ |= 0x00000004; + } + result.ephemeral_ = ephemeral_; + if (((from_bitField0_ & 0x00000008) != 0)) { + if (signatureBuilder_ == null) { + result.signature_ = signature_; } else { - result.x509Cert_ = x509CertBuilder_.build(); + result.signature_ = signatureBuilder_.build(); } - to_bitField0_ |= 0x00000002; + to_bitField0_ |= 0x00000008; } result.bitField0_ = to_bitField0_; onBuilt(); @@ -7807,21 +12655,27 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencrypt) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReencrypt)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt other) { - if (other == ch.epfl.dedis.lib.proto.OCS.AuthReencrypt.getDefaultInstance()) return this; - if (other.hasByzcoin()) { - mergeByzcoin(other.getByzcoin()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance()) return this; + if (other.hasWrite()) { + setWrite(other.getWrite()); } - if (other.hasX509Cert()) { - mergeX509Cert(other.getX509Cert()); + if (other.hasRead()) { + setRead(other.getRead()); + } + if (other.hasEphemeral()) { + setEphemeral(other.getEphemeral()); + } + if (other.hasSignature()) { + mergeSignature(other.getSignature()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -7830,13 +12684,17 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencrypt other) { @java.lang.Override public final boolean isInitialized() { - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - return false; - } + if (!hasWrite()) { + return false; } - if (hasX509Cert()) { - if (!getX509Cert().isInitialized()) { + if (!hasRead()) { + return false; + } + if (!hasEphemeral()) { + return false; + } + if (hasSignature()) { + if (!getSignature().isInitialized()) { return false; } } @@ -7848,11 +12706,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.AuthReencrypt parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReencrypt) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -7863,240 +12721,324 @@ public Builder mergeFrom( } private int bitField0_; - private ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin byzcoin_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder> byzcoinBuilder_; + private com.google.protobuf.ByteString write_ = com.google.protobuf.ByteString.EMPTY; /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; */ - public boolean hasByzcoin() { + public boolean hasWrite() { return ((bitField0_ & 0x00000001) != 0); } /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getByzcoin() { - if (byzcoinBuilder_ == null) { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; - } else { - return byzcoinBuilder_.getMessage(); - } + public com.google.protobuf.ByteString getWrite() { + return write_; } /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; */ - public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin value) { - if (byzcoinBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - byzcoin_ = value; - onChanged(); - } else { - byzcoinBuilder_.setMessage(value); - } - bitField0_ |= 0x00000001; + public Builder setWrite(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + write_ = value; + onChanged(); return this; } /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+       * Write is the proof containing the write request.
+       * 
+ * + * required bytes write = 1; */ - public Builder setByzcoin( - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder builderForValue) { - if (byzcoinBuilder_ == null) { - byzcoin_ = builderForValue.build(); - onChanged(); - } else { - byzcoinBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000001; + public Builder clearWrite() { + bitField0_ = (bitField0_ & ~0x00000001); + write_ = getDefaultInstance().getWrite(); + onChanged(); return this; } + + private com.google.protobuf.ByteString read_ = com.google.protobuf.ByteString.EMPTY; /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; */ - public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin value) { - if (byzcoinBuilder_ == null) { - if (((bitField0_ & 0x00000001) != 0) && - byzcoin_ != null && - byzcoin_ != ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance()) { - byzcoin_ = - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); - } else { - byzcoin_ = value; - } - onChanged(); - } else { - byzcoinBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000001; - return this; + public boolean hasRead() { + return ((bitField0_ & 0x00000002) != 0); } /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; */ - public Builder clearByzcoin() { - if (byzcoinBuilder_ == null) { - byzcoin_ = null; - onChanged(); - } else { - byzcoinBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000001); + public com.google.protobuf.ByteString getRead() { + return read_; + } + /** + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; + */ + public Builder setRead(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + read_ = value; + onChanged(); return this; } /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+       * Read is the proof that he has been accepted to read the secret.
+       * 
+ * + * required bytes read = 2; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder getByzcoinBuilder() { - bitField0_ |= 0x00000001; + public Builder clearRead() { + bitField0_ = (bitField0_ & ~0x00000002); + read_ = getDefaultInstance().getRead(); onChanged(); - return getByzcoinFieldBuilder().getBuilder(); + return this; + } + + private com.google.protobuf.ByteString ephemeral_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * Ephemeral can be non-nil to point to a key to which the data needs to be
+       * re-encrypted to, but then Signature also needs to be non-nil.
+       * 
+ * + * required bytes ephemeral = 3; + */ + public boolean hasEphemeral() { + return ((bitField0_ & 0x00000004) != 0); } /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+       * Ephemeral can be non-nil to point to a key to which the data needs to be
+       * re-encrypted to, but then Signature also needs to be non-nil.
+       * 
+ * + * required bytes ephemeral = 3; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder getByzcoinOrBuilder() { - if (byzcoinBuilder_ != null) { - return byzcoinBuilder_.getMessageOrBuilder(); - } else { - return byzcoin_ == null ? - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance() : byzcoin_; - } + public com.google.protobuf.ByteString getEphemeral() { + return ephemeral_; } /** - * optional .ocs.AuthReencryptByzCoin byzcoin = 1; + *
+       * Ephemeral can be non-nil to point to a key to which the data needs to be
+       * re-encrypted to, but then Signature also needs to be non-nil.
+       * 
+ * + * required bytes ephemeral = 3; */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder> - getByzcoinFieldBuilder() { - if (byzcoinBuilder_ == null) { - byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder>( - getByzcoin(), - getParentForChildren(), - isClean()); - byzcoin_ = null; - } - return byzcoinBuilder_; + public Builder setEphemeral(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + ephemeral_ = value; + onChanged(); + return this; + } + /** + *
+       * Ephemeral can be non-nil to point to a key to which the data needs to be
+       * re-encrypted to, but then Signature also needs to be non-nil.
+       * 
+ * + * required bytes ephemeral = 3; + */ + public Builder clearEphemeral() { + bitField0_ = (bitField0_ & ~0x00000004); + ephemeral_ = getDefaultInstance().getEphemeral(); + onChanged(); + return this; } - private ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert x509Cert_; + private ch.epfl.dedis.lib.proto.DarcProto.Signature signature_; private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder> x509CertBuilder_; + ch.epfl.dedis.lib.proto.DarcProto.Signature, ch.epfl.dedis.lib.proto.DarcProto.Signature.Builder, ch.epfl.dedis.lib.proto.DarcProto.SignatureOrBuilder> signatureBuilder_; /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+       * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+       * Read instance to make sure it's a valid reencryption-request.
+       * 
+ * + * optional .darc.Signature signature = 4; */ - public boolean hasX509Cert() { - return ((bitField0_ & 0x00000002) != 0); + public boolean hasSignature() { + return ((bitField0_ & 0x00000008) != 0); } /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+       * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+       * Read instance to make sure it's a valid reencryption-request.
+       * 
+ * + * optional .darc.Signature signature = 4; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getX509Cert() { - if (x509CertBuilder_ == null) { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; + public ch.epfl.dedis.lib.proto.DarcProto.Signature getSignature() { + if (signatureBuilder_ == null) { + return signature_ == null ? ch.epfl.dedis.lib.proto.DarcProto.Signature.getDefaultInstance() : signature_; } else { - return x509CertBuilder_.getMessage(); + return signatureBuilder_.getMessage(); } } /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+       * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+       * Read instance to make sure it's a valid reencryption-request.
+       * 
+ * + * optional .darc.Signature signature = 4; */ - public Builder setX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert value) { - if (x509CertBuilder_ == null) { + public Builder setSignature(ch.epfl.dedis.lib.proto.DarcProto.Signature value) { + if (signatureBuilder_ == null) { if (value == null) { throw new NullPointerException(); } - x509Cert_ = value; + signature_ = value; onChanged(); } else { - x509CertBuilder_.setMessage(value); + signatureBuilder_.setMessage(value); } - bitField0_ |= 0x00000002; + bitField0_ |= 0x00000008; return this; } /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+       * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+       * Read instance to make sure it's a valid reencryption-request.
+       * 
+ * + * optional .darc.Signature signature = 4; */ - public Builder setX509Cert( - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder builderForValue) { - if (x509CertBuilder_ == null) { - x509Cert_ = builderForValue.build(); + public Builder setSignature( + ch.epfl.dedis.lib.proto.DarcProto.Signature.Builder builderForValue) { + if (signatureBuilder_ == null) { + signature_ = builderForValue.build(); onChanged(); } else { - x509CertBuilder_.setMessage(builderForValue.build()); + signatureBuilder_.setMessage(builderForValue.build()); } - bitField0_ |= 0x00000002; + bitField0_ |= 0x00000008; return this; } /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+       * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+       * Read instance to make sure it's a valid reencryption-request.
+       * 
+ * + * optional .darc.Signature signature = 4; */ - public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert value) { - if (x509CertBuilder_ == null) { - if (((bitField0_ & 0x00000002) != 0) && - x509Cert_ != null && - x509Cert_ != ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance()) { - x509Cert_ = - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); + public Builder mergeSignature(ch.epfl.dedis.lib.proto.DarcProto.Signature value) { + if (signatureBuilder_ == null) { + if (((bitField0_ & 0x00000008) != 0) && + signature_ != null && + signature_ != ch.epfl.dedis.lib.proto.DarcProto.Signature.getDefaultInstance()) { + signature_ = + ch.epfl.dedis.lib.proto.DarcProto.Signature.newBuilder(signature_).mergeFrom(value).buildPartial(); } else { - x509Cert_ = value; + signature_ = value; } onChanged(); } else { - x509CertBuilder_.mergeFrom(value); + signatureBuilder_.mergeFrom(value); } - bitField0_ |= 0x00000002; + bitField0_ |= 0x00000008; return this; } /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+       * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+       * Read instance to make sure it's a valid reencryption-request.
+       * 
+ * + * optional .darc.Signature signature = 4; */ - public Builder clearX509Cert() { - if (x509CertBuilder_ == null) { - x509Cert_ = null; + public Builder clearSignature() { + if (signatureBuilder_ == null) { + signature_ = null; onChanged(); } else { - x509CertBuilder_.clear(); + signatureBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00000002); + bitField0_ = (bitField0_ & ~0x00000008); return this; } /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+       * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+       * Read instance to make sure it's a valid reencryption-request.
+       * 
+ * + * optional .darc.Signature signature = 4; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder getX509CertBuilder() { - bitField0_ |= 0x00000002; + public ch.epfl.dedis.lib.proto.DarcProto.Signature.Builder getSignatureBuilder() { + bitField0_ |= 0x00000008; onChanged(); - return getX509CertFieldBuilder().getBuilder(); + return getSignatureFieldBuilder().getBuilder(); } /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+       * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+       * Read instance to make sure it's a valid reencryption-request.
+       * 
+ * + * optional .darc.Signature signature = 4; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder getX509CertOrBuilder() { - if (x509CertBuilder_ != null) { - return x509CertBuilder_.getMessageOrBuilder(); + public ch.epfl.dedis.lib.proto.DarcProto.SignatureOrBuilder getSignatureOrBuilder() { + if (signatureBuilder_ != null) { + return signatureBuilder_.getMessageOrBuilder(); } else { - return x509Cert_ == null ? - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance() : x509Cert_; + return signature_ == null ? + ch.epfl.dedis.lib.proto.DarcProto.Signature.getDefaultInstance() : signature_; } } /** - * optional .ocs.AuthReencryptX509Cert x509cert = 2; + *
+       * If Ephemeral si non-nil, it must be signed by the darc responsible for the
+       * Read instance to make sure it's a valid reencryption-request.
+       * 
+ * + * optional .darc.Signature signature = 4; */ private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder> - getX509CertFieldBuilder() { - if (x509CertBuilder_ == null) { - x509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder>( - getX509Cert(), + ch.epfl.dedis.lib.proto.DarcProto.Signature, ch.epfl.dedis.lib.proto.DarcProto.Signature.Builder, ch.epfl.dedis.lib.proto.DarcProto.SignatureOrBuilder> + getSignatureFieldBuilder() { + if (signatureBuilder_ == null) { + signatureBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.DarcProto.Signature, ch.epfl.dedis.lib.proto.DarcProto.Signature.Builder, ch.epfl.dedis.lib.proto.DarcProto.SignatureOrBuilder>( + getSignature(), getParentForChildren(), isClean()); - x509Cert_ = null; + signature_ = null; } - return x509CertBuilder_; + return signatureBuilder_; } @java.lang.Override public final Builder setUnknownFields( @@ -8111,105 +13053,96 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.AuthReencrypt) + // @@protoc_insertion_point(builder_scope:ocs.AuthReencryptByzCoin) } - // @@protoc_insertion_point(class_scope:ocs.AuthReencrypt) - private static final ch.epfl.dedis.lib.proto.OCS.AuthReencrypt DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthReencryptByzCoin) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReencrypt(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin(); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public AuthReencrypt parsePartialFrom( + public AuthReencryptByzCoin parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new AuthReencrypt(input, extensionRegistry); + return new AuthReencryptByzCoin(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencrypt getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface AuthReencryptByzCoinOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.AuthReencryptByzCoin) + public interface AuthReencryptX509CertOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReencryptX509Cert) com.google.protobuf.MessageOrBuilder { /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required bytes write = 1; + * required bytes u = 1; */ - boolean hasWrite(); + boolean hasU(); /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required bytes write = 1; + * required bytes u = 1; */ - com.google.protobuf.ByteString getWrite(); + com.google.protobuf.ByteString getU(); /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required bytes read = 2; + * repeated bytes certificates = 2; */ - boolean hasRead(); + java.util.List getCertificatesList(); /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required bytes read = 2; + * repeated bytes certificates = 2; */ - com.google.protobuf.ByteString getRead(); + int getCertificatesCount(); + /** + * repeated bytes certificates = 2; + */ + com.google.protobuf.ByteString getCertificates(int index); } /** *
-   * AuthReencryptByzCoin holds the proof of the write instance, holding the secret itself.
-   * The proof of the read instance holds the ephemeral key. Both proofs can be
-   * verified using one of the stored ByzCoinIDs.
+   * AuthReencryptX509Cert holds the proof that at least a threshold number of clients
+   * accepted the reencryption.
+   * For each client, there must exist a certificate that can be verified by the
+   * CA certificate from X509Cert. Additionally, each client must sign the
+   * following message:
+   *   sha256( Secret | Ephemeral | Time )
    * 
* - * Protobuf type {@code ocs.AuthReencryptByzCoin} + * Protobuf type {@code ocs.AuthReencryptX509Cert} */ - public static final class AuthReencryptByzCoin extends + public static final class AuthReencryptX509Cert extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.AuthReencryptByzCoin) - AuthReencryptByzCoinOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthReencryptX509Cert) + AuthReencryptX509CertOrBuilder { private static final long serialVersionUID = 0L; - // Use AuthReencryptByzCoin.newBuilder() to construct. - private AuthReencryptByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthReencryptX509Cert.newBuilder() to construct. + private AuthReencryptX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private AuthReencryptByzCoin() { - write_ = com.google.protobuf.ByteString.EMPTY; - read_ = com.google.protobuf.ByteString.EMPTY; + private AuthReencryptX509Cert() { + u_ = com.google.protobuf.ByteString.EMPTY; + certificates_ = java.util.Collections.emptyList(); } @java.lang.Override @@ -8217,7 +13150,7 @@ private AuthReencryptByzCoin() { getUnknownFields() { return this.unknownFields; } - private AuthReencryptByzCoin( + private AuthReencryptX509Cert( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -8238,12 +13171,15 @@ private AuthReencryptByzCoin( break; case 10: { bitField0_ |= 0x00000001; - write_ = input.readBytes(); + u_ = input.readBytes(); break; } case 18: { - bitField0_ |= 0x00000002; - read_ = input.readBytes(); + if (!((mutable_bitField0_ & 0x00000002) != 0)) { + certificates_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + certificates_.add(input.readBytes()); break; } default: { @@ -8261,68 +13197,62 @@ private AuthReencryptByzCoin( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { + if (((mutable_bitField0_ & 0x00000002) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); // C + } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder.class); } private int bitField0_; - public static final int WRITE_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString write_; + public static final int U_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString u_; /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required bytes write = 1; + * required bytes u = 1; */ - public boolean hasWrite() { + public boolean hasU() { return ((bitField0_ & 0x00000001) != 0); } /** - *
-     * Write is the proof containing the write request.
-     * 
- * - * required bytes write = 1; + * required bytes u = 1; */ - public com.google.protobuf.ByteString getWrite() { - return write_; + public com.google.protobuf.ByteString getU() { + return u_; } - public static final int READ_FIELD_NUMBER = 2; - private com.google.protobuf.ByteString read_; + public static final int CERTIFICATES_FIELD_NUMBER = 2; + private java.util.List certificates_; /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required bytes read = 2; + * repeated bytes certificates = 2; */ - public boolean hasRead() { - return ((bitField0_ & 0x00000002) != 0); + public java.util.List + getCertificatesList() { + return certificates_; } /** - *
-     * Read is the proof that he has been accepted to read the secret.
-     * 
- * - * required bytes read = 2; + * repeated bytes certificates = 2; */ - public com.google.protobuf.ByteString getRead() { - return read_; + public int getCertificatesCount() { + return certificates_.size(); + } + /** + * repeated bytes certificates = 2; + */ + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); } private byte memoizedIsInitialized = -1; @@ -8332,11 +13262,7 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasWrite()) { - memoizedIsInitialized = 0; - return false; - } - if (!hasRead()) { + if (!hasU()) { memoizedIsInitialized = 0; return false; } @@ -8348,10 +13274,10 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, write_); + output.writeBytes(1, u_); } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeBytes(2, read_); + for (int i = 0; i < certificates_.size(); i++) { + output.writeBytes(2, certificates_.get(i)); } unknownFields.writeTo(output); } @@ -8362,13 +13288,18 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, write_); - } - if (((bitField0_ & 0x00000002) != 0)) { + if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeBytesSize(2, read_); + .computeBytesSize(1, u_); + } + { + int dataSize = 0; + for (int i = 0; i < certificates_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(certificates_.get(i)); + } + size += dataSize; + size += 1 * getCertificatesList().size(); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -8380,21 +13311,18 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin other = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin) obj; + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert other = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert) obj; - if (hasWrite() != other.hasWrite()) return false; - if (hasWrite()) { - if (!getWrite() - .equals(other.getWrite())) return false; - } - if (hasRead() != other.hasRead()) return false; - if (hasRead()) { - if (!getRead() - .equals(other.getRead())) return false; + if (hasU() != other.hasU()) return false; + if (hasU()) { + if (!getU() + .equals(other.getU())) return false; } + if (!getCertificatesList() + .equals(other.getCertificatesList())) return false; if (!unknownFields.equals(other.unknownFields)) return false; return true; } @@ -8406,82 +13334,82 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasWrite()) { - hash = (37 * hash) + WRITE_FIELD_NUMBER; - hash = (53 * hash) + getWrite().hashCode(); + if (hasU()) { + hash = (37 * hash) + U_FIELD_NUMBER; + hash = (53 * hash) + getU().hashCode(); } - if (hasRead()) { - hash = (37 * hash) + READ_FIELD_NUMBER; - hash = (53 * hash) + getRead().hashCode(); + if (getCertificatesCount() > 0) { + hash = (37 * hash) + CERTIFICATES_FIELD_NUMBER; + hash = (53 * hash) + getCertificatesList().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -8494,7 +13422,7 @@ public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -8511,31 +13439,34 @@ protected Builder newBuilderForType( } /** *
-     * AuthReencryptByzCoin holds the proof of the write instance, holding the secret itself.
-     * The proof of the read instance holds the ephemeral key. Both proofs can be
-     * verified using one of the stored ByzCoinIDs.
+     * AuthReencryptX509Cert holds the proof that at least a threshold number of clients
+     * accepted the reencryption.
+     * For each client, there must exist a certificate that can be verified by the
+     * CA certificate from X509Cert. Additionally, each client must sign the
+     * following message:
+     *   sha256( Secret | Ephemeral | Time )
      * 
* - * Protobuf type {@code ocs.AuthReencryptByzCoin} + * Protobuf type {@code ocs.AuthReencryptX509Cert} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.AuthReencryptByzCoin) - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoinOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthReencryptX509Cert) + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -8553,9 +13484,9 @@ private void maybeForceBuilderInitialization() { @java.lang.Override public Builder clear() { super.clear(); - write_ = com.google.protobuf.ByteString.EMPTY; + u_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); - read_ = com.google.protobuf.ByteString.EMPTY; + certificates_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); return this; } @@ -8563,17 +13494,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin build() { - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert build() { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -8581,18 +13512,19 @@ public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin buildPartial() { - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin result = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin(this); + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert result = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { to_bitField0_ |= 0x00000001; } - result.write_ = write_; - if (((from_bitField0_ & 0x00000002) != 0)) { - to_bitField0_ |= 0x00000002; + result.u_ = u_; + if (((bitField0_ & 0x00000002) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); + bitField0_ = (bitField0_ & ~0x00000002); } - result.read_ = read_; + result.certificates_ = certificates_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -8632,21 +13564,28 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin other) { - if (other == ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin.getDefaultInstance()) return this; - if (other.hasWrite()) { - setWrite(other.getWrite()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance()) return this; + if (other.hasU()) { + setU(other.getU()); } - if (other.hasRead()) { - setRead(other.getRead()); + if (!other.certificates_.isEmpty()) { + if (certificates_.isEmpty()) { + certificates_ = other.certificates_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureCertificatesIsMutable(); + certificates_.addAll(other.certificates_); + } + onChanged(); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -8655,10 +13594,7 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin other) @java.lang.Override public final boolean isInitialized() { - if (!hasWrite()) { - return false; - } - if (!hasRead()) { + if (!hasU()) { return false; } return true; @@ -8669,11 +13605,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -8684,104 +13620,110 @@ public Builder mergeFrom( } private int bitField0_; - private com.google.protobuf.ByteString write_ = com.google.protobuf.ByteString.EMPTY; + private com.google.protobuf.ByteString u_ = com.google.protobuf.ByteString.EMPTY; /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required bytes write = 1; + * required bytes u = 1; */ - public boolean hasWrite() { + public boolean hasU() { return ((bitField0_ & 0x00000001) != 0); } /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required bytes write = 1; + * required bytes u = 1; */ - public com.google.protobuf.ByteString getWrite() { - return write_; + public com.google.protobuf.ByteString getU() { + return u_; } /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required bytes write = 1; + * required bytes u = 1; */ - public Builder setWrite(com.google.protobuf.ByteString value) { + public Builder setU(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000001; - write_ = value; + u_ = value; onChanged(); return this; } /** - *
-       * Write is the proof containing the write request.
-       * 
- * - * required bytes write = 1; + * required bytes u = 1; */ - public Builder clearWrite() { + public Builder clearU() { bitField0_ = (bitField0_ & ~0x00000001); - write_ = getDefaultInstance().getWrite(); + u_ = getDefaultInstance().getU(); onChanged(); return this; } - private com.google.protobuf.ByteString read_ = com.google.protobuf.ByteString.EMPTY; + private java.util.List certificates_ = java.util.Collections.emptyList(); + private void ensureCertificatesIsMutable() { + if (!((bitField0_ & 0x00000002) != 0)) { + certificates_ = new java.util.ArrayList(certificates_); + bitField0_ |= 0x00000002; + } + } /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required bytes read = 2; + * repeated bytes certificates = 2; */ - public boolean hasRead() { - return ((bitField0_ & 0x00000002) != 0); + public java.util.List + getCertificatesList() { + return ((bitField0_ & 0x00000002) != 0) ? + java.util.Collections.unmodifiableList(certificates_) : certificates_; } /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required bytes read = 2; + * repeated bytes certificates = 2; */ - public com.google.protobuf.ByteString getRead() { - return read_; + public int getCertificatesCount() { + return certificates_.size(); } /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required bytes read = 2; + * repeated bytes certificates = 2; */ - public Builder setRead(com.google.protobuf.ByteString value) { + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); + } + /** + * repeated bytes certificates = 2; + */ + public Builder setCertificates( + int index, com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } - bitField0_ |= 0x00000002; - read_ = value; + ensureCertificatesIsMutable(); + certificates_.set(index, value); onChanged(); return this; } /** - *
-       * Read is the proof that he has been accepted to read the secret.
-       * 
- * - * required bytes read = 2; + * repeated bytes certificates = 2; */ - public Builder clearRead() { + public Builder addCertificates(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCertificatesIsMutable(); + certificates_.add(value); + onChanged(); + return this; + } + /** + * repeated bytes certificates = 2; + */ + public Builder addAllCertificates( + java.lang.Iterable values) { + ensureCertificatesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, certificates_); + onChanged(); + return this; + } + /** + * repeated bytes certificates = 2; + */ + public Builder clearCertificates() { + certificates_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000002); - read_ = getDefaultInstance().getRead(); onChanged(); return this; } @@ -8798,96 +13740,95 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.AuthReencryptByzCoin) + // @@protoc_insertion_point(builder_scope:ocs.AuthReencryptX509Cert) } - // @@protoc_insertion_point(class_scope:ocs.AuthReencryptByzCoin) - private static final ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthReencryptX509Cert) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert(); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public AuthReencryptByzCoin parsePartialFrom( + public AuthReencryptX509Cert parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new AuthReencryptByzCoin(input, extensionRegistry); + return new AuthReencryptX509Cert(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptByzCoin getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface AuthReencryptX509CertOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.AuthReencryptX509Cert) + public interface AuthReshareOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReshare) com.google.protobuf.MessageOrBuilder { /** - * required bytes secret = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; + */ + boolean hasByzcoin(); + /** + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - boolean hasSecret(); + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getByzcoin(); /** - * required bytes secret = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - com.google.protobuf.ByteString getSecret(); + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder getByzcoinOrBuilder(); /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - java.util.List getCertificatesList(); + boolean hasX509Cert(); /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - int getCertificatesCount(); + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getX509Cert(); /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - com.google.protobuf.ByteString getCertificates(int index); + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder getX509CertOrBuilder(); } /** *
-   * AuthReencryptX509Cert holds the proof that at least a threshold number of clients
-   * accepted the reencryption.
-   * For each client, there must exist a certificate that can be verified by the
-   * CA certificate from PolicyX509Cert. Additionally, each client must sign the
-   * following message:
-   *   sha256( Secret | Ephemeral | Time )
+   * AuthReshare holds the proof that at least a threshold number of clients accepted the
+   * request to reshare the secret key. The authentication must hold the new roster, as
+   * well as the proof that the new roster should be applied to a given OCS.
    * 
* - * Protobuf type {@code ocs.AuthReencryptX509Cert} + * Protobuf type {@code ocs.AuthReshare} */ - public static final class AuthReencryptX509Cert extends + public static final class AuthReshare extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.AuthReencryptX509Cert) - AuthReencryptX509CertOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthReshare) + AuthReshareOrBuilder { private static final long serialVersionUID = 0L; - // Use AuthReencryptX509Cert.newBuilder() to construct. - private AuthReencryptX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthReshare.newBuilder() to construct. + private AuthReshare(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private AuthReencryptX509Cert() { - secret_ = com.google.protobuf.ByteString.EMPTY; - certificates_ = java.util.Collections.emptyList(); + private AuthReshare() { } @java.lang.Override @@ -8895,7 +13836,7 @@ private AuthReencryptX509Cert() { getUnknownFields() { return this.unknownFields; } - private AuthReencryptX509Cert( + private AuthReshare( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -8915,16 +13856,29 @@ private AuthReencryptX509Cert( done = true; break; case 10: { + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder subBuilder = null; + if (((bitField0_ & 0x00000001) != 0)) { + subBuilder = byzcoin_.toBuilder(); + } + byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(byzcoin_); + byzcoin_ = subBuilder.buildPartial(); + } bitField0_ |= 0x00000001; - secret_ = input.readBytes(); break; } case 18: { - if (!((mutable_bitField0_ & 0x00000002) != 0)) { - certificates_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000002; + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = x509Cert_.toBuilder(); } - certificates_.add(input.readBytes()); + x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(x509Cert_); + x509Cert_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; break; } default: { @@ -8942,62 +13896,64 @@ private AuthReencryptX509Cert( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { - if (((mutable_bitField0_ & 0x00000002) != 0)) { - certificates_ = java.util.Collections.unmodifiableList(certificates_); // C - } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReshare.class, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder.class); } private int bitField0_; - public static final int SECRET_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString secret_; + public static final int BYZCOIN_FIELD_NUMBER = 1; + private ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin byzcoin_; /** - * required bytes secret = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public boolean hasSecret() { + public boolean hasByzcoin() { return ((bitField0_ & 0x00000001) != 0); } /** - * required bytes secret = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getByzcoin() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; + } + /** + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public com.google.protobuf.ByteString getSecret() { - return secret_; + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder getByzcoinOrBuilder() { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; } - public static final int CERTIFICATES_FIELD_NUMBER = 2; - private java.util.List certificates_; + public static final int X509CERT_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert x509Cert_; /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public java.util.List - getCertificatesList() { - return certificates_; + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000002) != 0); } /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public int getCertificatesCount() { - return certificates_.size(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getX509Cert() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; } /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public com.google.protobuf.ByteString getCertificates(int index) { - return certificates_.get(index); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder getX509CertOrBuilder() { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; } private byte memoizedIsInitialized = -1; @@ -9007,9 +13963,11 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasSecret()) { - memoizedIsInitialized = 0; - return false; + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } } memoizedIsInitialized = 1; return true; @@ -9019,10 +13977,10 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, secret_); + output.writeMessage(1, getByzcoin()); } - for (int i = 0; i < certificates_.size(); i++) { - output.writeBytes(2, certificates_.get(i)); + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getX509Cert()); } unknownFields.writeTo(output); } @@ -9035,16 +13993,11 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, secret_); + .computeMessageSize(1, getByzcoin()); } - { - int dataSize = 0; - for (int i = 0; i < certificates_.size(); i++) { - dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(certificates_.get(i)); - } - size += dataSize; - size += 1 * getCertificatesList().size(); + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getX509Cert()); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -9056,18 +14009,21 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshare)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert other = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert) obj; + ch.epfl.dedis.lib.proto.OCS.AuthReshare other = (ch.epfl.dedis.lib.proto.OCS.AuthReshare) obj; - if (hasSecret() != other.hasSecret()) return false; - if (hasSecret()) { - if (!getSecret() - .equals(other.getSecret())) return false; + if (hasByzcoin() != other.hasByzcoin()) return false; + if (hasByzcoin()) { + if (!getByzcoin() + .equals(other.getByzcoin())) return false; + } + if (hasX509Cert() != other.hasX509Cert()) return false; + if (hasX509Cert()) { + if (!getX509Cert() + .equals(other.getX509Cert())) return false; } - if (!getCertificatesList() - .equals(other.getCertificatesList())) return false; if (!unknownFields.equals(other.unknownFields)) return false; return true; } @@ -9079,82 +14035,82 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasSecret()) { - hash = (37 * hash) + SECRET_FIELD_NUMBER; - hash = (53 * hash) + getSecret().hashCode(); + if (hasByzcoin()) { + hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; + hash = (53 * hash) + getByzcoin().hashCode(); } - if (getCertificatesCount() > 0) { - hash = (37 * hash) + CERTIFICATES_FIELD_NUMBER; - hash = (53 * hash) + getCertificatesList().hashCode(); + if (hasX509Cert()) { + hash = (37 * hash) + X509CERT_FIELD_NUMBER; + hash = (53 * hash) + getX509Cert().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -9167,7 +14123,7 @@ public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReshare prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -9184,34 +14140,31 @@ protected Builder newBuilderForType( } /** *
-     * AuthReencryptX509Cert holds the proof that at least a threshold number of clients
-     * accepted the reencryption.
-     * For each client, there must exist a certificate that can be verified by the
-     * CA certificate from PolicyX509Cert. Additionally, each client must sign the
-     * following message:
-     *   sha256( Secret | Ephemeral | Time )
+     * AuthReshare holds the proof that at least a threshold number of clients accepted the
+     * request to reshare the secret key. The authentication must hold the new roster, as
+     * well as the proof that the new roster should be applied to a given OCS.
      * 
* - * Protobuf type {@code ocs.AuthReencryptX509Cert} + * Protobuf type {@code ocs.AuthReshare} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.AuthReencryptX509Cert) - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509CertOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthReshare) + ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReshare.class, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReshare.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -9224,14 +14177,24 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { + getByzcoinFieldBuilder(); + getX509CertFieldBuilder(); } } @java.lang.Override public Builder clear() { super.clear(); - secret_ = com.google.protobuf.ByteString.EMPTY; + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + } else { + byzcoinBuilder_.clear(); + } bitField0_ = (bitField0_ & ~0x00000001); - certificates_ = java.util.Collections.emptyList(); + if (x509CertBuilder_ == null) { + x509Cert_ = null; + } else { + x509CertBuilder_.clear(); + } bitField0_ = (bitField0_ & ~0x00000002); return this; } @@ -9239,17 +14202,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReencryptX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshare getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert build() { - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshare build() { + ch.epfl.dedis.lib.proto.OCS.AuthReshare result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -9257,19 +14220,26 @@ public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert buildPartial() { - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert result = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert(this); + public ch.epfl.dedis.lib.proto.OCS.AuthReshare buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReshare result = new ch.epfl.dedis.lib.proto.OCS.AuthReshare(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { + if (byzcoinBuilder_ == null) { + result.byzcoin_ = byzcoin_; + } else { + result.byzcoin_ = byzcoinBuilder_.build(); + } to_bitField0_ |= 0x00000001; } - result.secret_ = secret_; - if (((bitField0_ & 0x00000002) != 0)) { - certificates_ = java.util.Collections.unmodifiableList(certificates_); - bitField0_ = (bitField0_ & ~0x00000002); + if (((from_bitField0_ & 0x00000002) != 0)) { + if (x509CertBuilder_ == null) { + result.x509Cert_ = x509Cert_; + } else { + result.x509Cert_ = x509CertBuilder_.build(); + } + to_bitField0_ |= 0x00000002; } - result.certificates_ = certificates_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -9309,28 +14279,21 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshare) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReshare)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert other) { - if (other == ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert.getDefaultInstance()) return this; - if (other.hasSecret()) { - setSecret(other.getSecret()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReshare other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance()) return this; + if (other.hasByzcoin()) { + mergeByzcoin(other.getByzcoin()); } - if (!other.certificates_.isEmpty()) { - if (certificates_.isEmpty()) { - certificates_ = other.certificates_; - bitField0_ = (bitField0_ & ~0x00000002); - } else { - ensureCertificatesIsMutable(); - certificates_.addAll(other.certificates_); - } - onChanged(); + if (other.hasX509Cert()) { + mergeX509Cert(other.getX509Cert()); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -9339,8 +14302,10 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert other @java.lang.Override public final boolean isInitialized() { - if (!hasSecret()) { - return false; + if (hasByzcoin()) { + if (!getByzcoin().isInitialized()) { + return false; + } } return true; } @@ -9350,11 +14315,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AuthReshare parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReshare) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -9365,112 +14330,240 @@ public Builder mergeFrom( } private int bitField0_; - private com.google.protobuf.ByteString secret_ = com.google.protobuf.ByteString.EMPTY; + private ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin byzcoin_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder> byzcoinBuilder_; /** - * required bytes secret = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public boolean hasSecret() { + public boolean hasByzcoin() { return ((bitField0_ & 0x00000001) != 0); } /** - * required bytes secret = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public com.google.protobuf.ByteString getSecret() { - return secret_; + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getByzcoin() { + if (byzcoinBuilder_ == null) { + return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; + } else { + return byzcoinBuilder_.getMessage(); + } } /** - * required bytes secret = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public Builder setSecret(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - secret_ = value; - onChanged(); + public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin value) { + if (byzcoinBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + byzcoin_ = value; + onChanged(); + } else { + byzcoinBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.AuthReshareByzCoin byzcoin = 1; + */ + public Builder setByzcoin( + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder builderForValue) { + if (byzcoinBuilder_ == null) { + byzcoin_ = builderForValue.build(); + onChanged(); + } else { + byzcoinBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + return this; + } + /** + * optional .ocs.AuthReshareByzCoin byzcoin = 1; + */ + public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin value) { + if (byzcoinBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) && + byzcoin_ != null && + byzcoin_ != ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance()) { + byzcoin_ = + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); + } else { + byzcoin_ = value; + } + onChanged(); + } else { + byzcoinBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000001; return this; } /** - * required bytes secret = 1; + * optional .ocs.AuthReshareByzCoin byzcoin = 1; */ - public Builder clearSecret() { + public Builder clearByzcoin() { + if (byzcoinBuilder_ == null) { + byzcoin_ = null; + onChanged(); + } else { + byzcoinBuilder_.clear(); + } bitField0_ = (bitField0_ & ~0x00000001); - secret_ = getDefaultInstance().getSecret(); - onChanged(); return this; } + /** + * optional .ocs.AuthReshareByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder getByzcoinBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getByzcoinFieldBuilder().getBuilder(); + } + /** + * optional .ocs.AuthReshareByzCoin byzcoin = 1; + */ + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder getByzcoinOrBuilder() { + if (byzcoinBuilder_ != null) { + return byzcoinBuilder_.getMessageOrBuilder(); + } else { + return byzcoin_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; + } + } + /** + * optional .ocs.AuthReshareByzCoin byzcoin = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder> + getByzcoinFieldBuilder() { + if (byzcoinBuilder_ == null) { + byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder>( + getByzcoin(), + getParentForChildren(), + isClean()); + byzcoin_ = null; + } + return byzcoinBuilder_; + } - private java.util.List certificates_ = java.util.Collections.emptyList(); - private void ensureCertificatesIsMutable() { - if (!((bitField0_ & 0x00000002) != 0)) { - certificates_ = new java.util.ArrayList(certificates_); - bitField0_ |= 0x00000002; - } + private ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert x509Cert_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder> x509CertBuilder_; + /** + * optional .ocs.AuthReshareX509Cert x509cert = 2; + */ + public boolean hasX509Cert() { + return ((bitField0_ & 0x00000002) != 0); } /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public java.util.List - getCertificatesList() { - return ((bitField0_ & 0x00000002) != 0) ? - java.util.Collections.unmodifiableList(certificates_) : certificates_; + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getX509Cert() { + if (x509CertBuilder_ == null) { + return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; + } else { + return x509CertBuilder_.getMessage(); + } } /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public int getCertificatesCount() { - return certificates_.size(); + public Builder setX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert value) { + if (x509CertBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + x509Cert_ = value; + onChanged(); + } else { + x509CertBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; } /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public com.google.protobuf.ByteString getCertificates(int index) { - return certificates_.get(index); + public Builder setX509Cert( + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder builderForValue) { + if (x509CertBuilder_ == null) { + x509Cert_ = builderForValue.build(); + onChanged(); + } else { + x509CertBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; } /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public Builder setCertificates( - int index, com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureCertificatesIsMutable(); - certificates_.set(index, value); - onChanged(); + public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert value) { + if (x509CertBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + x509Cert_ != null && + x509Cert_ != ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance()) { + x509Cert_ = + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); + } else { + x509Cert_ = value; + } + onChanged(); + } else { + x509CertBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; return this; } /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public Builder addCertificates(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureCertificatesIsMutable(); - certificates_.add(value); - onChanged(); + public Builder clearX509Cert() { + if (x509CertBuilder_ == null) { + x509Cert_ = null; + onChanged(); + } else { + x509CertBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); return this; } /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public Builder addAllCertificates( - java.lang.Iterable values) { - ensureCertificatesIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, certificates_); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder getX509CertBuilder() { + bitField0_ |= 0x00000002; onChanged(); - return this; + return getX509CertFieldBuilder().getBuilder(); } /** - * repeated bytes certificates = 2; + * optional .ocs.AuthReshareX509Cert x509cert = 2; */ - public Builder clearCertificates() { - certificates_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000002); - onChanged(); - return this; + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder getX509CertOrBuilder() { + if (x509CertBuilder_ != null) { + return x509CertBuilder_.getMessageOrBuilder(); + } else { + return x509Cert_ == null ? + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; + } + } + /** + * optional .ocs.AuthReshareX509Cert x509cert = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder> + getX509CertFieldBuilder() { + if (x509CertBuilder_ == null) { + x509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder>( + getX509Cert(), + getParentForChildren(), + isClean()); + x509Cert_ = null; + } + return x509CertBuilder_; } @java.lang.Override public final Builder setUnknownFields( @@ -9485,95 +14578,79 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.AuthReencryptX509Cert) + // @@protoc_insertion_point(builder_scope:ocs.AuthReshare) } - // @@protoc_insertion_point(class_scope:ocs.AuthReencryptX509Cert) - private static final ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthReshare) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReshare DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReshare(); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthReshare getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public AuthReencryptX509Cert parsePartialFrom( + public AuthReshare parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new AuthReencryptX509Cert(input, extensionRegistry); + return new AuthReshare(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReencryptX509Cert getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshare getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface AuthReshareOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.AuthReshare) + public interface AuthReshareByzCoinOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReshareByzCoin) com.google.protobuf.MessageOrBuilder { /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - boolean hasByzcoin(); - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getByzcoin(); - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder getByzcoinOrBuilder(); - - /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; - */ - boolean hasX509Cert(); - /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; + * required bytes reshare = 1; */ - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getX509Cert(); + boolean hasReshare(); /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; + * required bytes reshare = 1; */ - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder getX509CertOrBuilder(); + com.google.protobuf.ByteString getReshare(); } /** *
-   * AuthReshare holds the proof that at least a threshold number of clients accepted the
-   * request to reshare the secret key. The authentication must hold the new roster, as
-   * well as the proof that the new roster should be applied to a given OCS.
+   * AuthReshareByzCoin holds the byzcoin-proof that contains the latest OCS-instance
+   * which includes the roster. The OCS-nodes will make sure that the version of the
+   * OCS-instance is bigger than the current version.
    * 
* - * Protobuf type {@code ocs.AuthReshare} + * Protobuf type {@code ocs.AuthReshareByzCoin} */ - public static final class AuthReshare extends + public static final class AuthReshareByzCoin extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.AuthReshare) - AuthReshareOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthReshareByzCoin) + AuthReshareByzCoinOrBuilder { private static final long serialVersionUID = 0L; - // Use AuthReshare.newBuilder() to construct. - private AuthReshare(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthReshareByzCoin.newBuilder() to construct. + private AuthReshareByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private AuthReshare() { + private AuthReshareByzCoin() { + reshare_ = com.google.protobuf.ByteString.EMPTY; } @java.lang.Override @@ -9581,7 +14658,7 @@ private AuthReshare() { getUnknownFields() { return this.unknownFields; } - private AuthReshare( + private AuthReshareByzCoin( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -9601,29 +14678,8 @@ private AuthReshare( done = true; break; case 10: { - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder subBuilder = null; - if (((bitField0_ & 0x00000001) != 0)) { - subBuilder = byzcoin_.toBuilder(); - } - byzcoin_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(byzcoin_); - byzcoin_ = subBuilder.buildPartial(); - } bitField0_ |= 0x00000001; - break; - } - case 18: { - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder subBuilder = null; - if (((bitField0_ & 0x00000002) != 0)) { - subBuilder = x509Cert_.toBuilder(); - } - x509Cert_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.parser(), extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(x509Cert_); - x509Cert_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000002; + reshare_ = input.readBytes(); break; } default: { @@ -9647,58 +14703,31 @@ private AuthReshare( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReshare.class, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder.class); } private int bitField0_; - public static final int BYZCOIN_FIELD_NUMBER = 1; - private ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin byzcoin_; + public static final int RESHARE_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString reshare_; /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; + * required bytes reshare = 1; */ - public boolean hasByzcoin() { + public boolean hasReshare() { return ((bitField0_ & 0x00000001) != 0); } /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getByzcoin() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; - } - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder getByzcoinOrBuilder() { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; - } - - public static final int X509CERT_FIELD_NUMBER = 2; - private ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert x509Cert_; - /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; - */ - public boolean hasX509Cert() { - return ((bitField0_ & 0x00000002) != 0); - } - /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; - */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getX509Cert() { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; - } - /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; + * required bytes reshare = 1; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder getX509CertOrBuilder() { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; + public com.google.protobuf.ByteString getReshare() { + return reshare_; } private byte memoizedIsInitialized = -1; @@ -9708,11 +14737,9 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - memoizedIsInitialized = 0; - return false; - } + if (!hasReshare()) { + memoizedIsInitialized = 0; + return false; } memoizedIsInitialized = 1; return true; @@ -9722,10 +14749,7 @@ public final boolean isInitialized() { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { - output.writeMessage(1, getByzcoin()); - } - if (((bitField0_ & 0x00000002) != 0)) { - output.writeMessage(2, getX509Cert()); + output.writeBytes(1, reshare_); } unknownFields.writeTo(output); } @@ -9738,11 +14762,7 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, getByzcoin()); - } - if (((bitField0_ & 0x00000002) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, getX509Cert()); + .computeBytesSize(1, reshare_); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -9754,20 +14774,15 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshare)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.AuthReshare other = (ch.epfl.dedis.lib.proto.OCS.AuthReshare) obj; + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin other = (ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin) obj; - if (hasByzcoin() != other.hasByzcoin()) return false; - if (hasByzcoin()) { - if (!getByzcoin() - .equals(other.getByzcoin())) return false; - } - if (hasX509Cert() != other.hasX509Cert()) return false; - if (hasX509Cert()) { - if (!getX509Cert() - .equals(other.getX509Cert())) return false; + if (hasReshare() != other.hasReshare()) return false; + if (hasReshare()) { + if (!getReshare() + .equals(other.getReshare())) return false; } if (!unknownFields.equals(other.unknownFields)) return false; return true; @@ -9780,82 +14795,78 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasByzcoin()) { - hash = (37 * hash) + BYZCOIN_FIELD_NUMBER; - hash = (53 * hash) + getByzcoin().hashCode(); - } - if (hasX509Cert()) { - hash = (37 * hash) + X509CERT_FIELD_NUMBER; - hash = (53 * hash) + getX509Cert().hashCode(); + if (hasReshare()) { + hash = (37 * hash) + RESHARE_FIELD_NUMBER; + hash = (53 * hash) + getReshare().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -9868,7 +14879,7 @@ public static ch.epfl.dedis.lib.proto.OCS.AuthReshare parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReshare prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -9884,32 +14895,32 @@ protected Builder newBuilderForType( return builder; } /** - *
-     * AuthReshare holds the proof that at least a threshold number of clients accepted the
-     * request to reshare the secret key. The authentication must hold the new roster, as
-     * well as the proof that the new roster should be applied to a given OCS.
+     * 
+     * AuthReshareByzCoin holds the byzcoin-proof that contains the latest OCS-instance
+     * which includes the roster. The OCS-nodes will make sure that the version of the
+     * OCS-instance is bigger than the current version.
      * 
* - * Protobuf type {@code ocs.AuthReshare} + * Protobuf type {@code ocs.AuthReshareByzCoin} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.AuthReshare) - ch.epfl.dedis.lib.proto.OCS.AuthReshareOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthReshareByzCoin) + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReshare.class, ch.epfl.dedis.lib.proto.OCS.AuthReshare.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReshare.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -9922,393 +14933,163 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessageV3 .alwaysUseFieldBuilders) { - getByzcoinFieldBuilder(); - getX509CertFieldBuilder(); } } @java.lang.Override public Builder clear() { super.clear(); - if (byzcoinBuilder_ == null) { - byzcoin_ = null; - } else { - byzcoinBuilder_.clear(); - } + reshare_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000001); - if (x509CertBuilder_ == null) { - x509Cert_ = null; - } else { - x509CertBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshare_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshare getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshare build() { - ch.epfl.dedis.lib.proto.OCS.AuthReshare result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin build() { + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } - return result; - } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshare buildPartial() { - ch.epfl.dedis.lib.proto.OCS.AuthReshare result = new ch.epfl.dedis.lib.proto.OCS.AuthReshare(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) != 0)) { - if (byzcoinBuilder_ == null) { - result.byzcoin_ = byzcoin_; - } else { - result.byzcoin_ = byzcoinBuilder_.build(); - } - to_bitField0_ |= 0x00000001; - } - if (((from_bitField0_ & 0x00000002) != 0)) { - if (x509CertBuilder_ == null) { - result.x509Cert_ = x509Cert_; - } else { - result.x509Cert_ = x509CertBuilder_.build(); - } - to_bitField0_ |= 0x00000002; - } - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - @java.lang.Override - public Builder clone() { - return super.clone(); - } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); - } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); - } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); - } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); - } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); - } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshare) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReshare)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReshare other) { - if (other == ch.epfl.dedis.lib.proto.OCS.AuthReshare.getDefaultInstance()) return this; - if (other.hasByzcoin()) { - mergeByzcoin(other.getByzcoin()); - } - if (other.hasX509Cert()) { - mergeX509Cert(other.getX509Cert()); - } - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @java.lang.Override - public final boolean isInitialized() { - if (hasByzcoin()) { - if (!getByzcoin().isInitialized()) { - return false; - } - } - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.AuthReshare parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReshare) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - private ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin byzcoin_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder> byzcoinBuilder_; - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - public boolean hasByzcoin() { - return ((bitField0_ & 0x00000001) != 0); - } - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getByzcoin() { - if (byzcoinBuilder_ == null) { - return byzcoin_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; - } else { - return byzcoinBuilder_.getMessage(); - } - } - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - public Builder setByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin value) { - if (byzcoinBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - byzcoin_ = value; - onChanged(); - } else { - byzcoinBuilder_.setMessage(value); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - public Builder setByzcoin( - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder builderForValue) { - if (byzcoinBuilder_ == null) { - byzcoin_ = builderForValue.build(); - onChanged(); - } else { - byzcoinBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - public Builder mergeByzcoin(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin value) { - if (byzcoinBuilder_ == null) { - if (((bitField0_ & 0x00000001) != 0) && - byzcoin_ != null && - byzcoin_ != ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance()) { - byzcoin_ = - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.newBuilder(byzcoin_).mergeFrom(value).buildPartial(); - } else { - byzcoin_ = value; - } - onChanged(); - } else { - byzcoinBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - public Builder clearByzcoin() { - if (byzcoinBuilder_ == null) { - byzcoin_ = null; - onChanged(); - } else { - byzcoinBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000001); - return this; - } - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder getByzcoinBuilder() { - bitField0_ |= 0x00000001; - onChanged(); - return getByzcoinFieldBuilder().getBuilder(); - } - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder getByzcoinOrBuilder() { - if (byzcoinBuilder_ != null) { - return byzcoinBuilder_.getMessageOrBuilder(); - } else { - return byzcoin_ == null ? - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance() : byzcoin_; - } + return result; } - /** - * optional .ocs.AuthReshareByzCoin byzcoin = 1; - */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder> - getByzcoinFieldBuilder() { - if (byzcoinBuilder_ == null) { - byzcoinBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder>( - getByzcoin(), - getParentForChildren(), - isClean()); - byzcoin_ = null; + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin result = new ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; } - return byzcoinBuilder_; + result.reshare_ = reshare_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; } - private ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert x509Cert_; - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder> x509CertBuilder_; - /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; - */ - public boolean hasX509Cert() { - return ((bitField0_ & 0x00000002) != 0); + @java.lang.Override + public Builder clone() { + return super.clone(); } - /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; - */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getX509Cert() { - if (x509CertBuilder_ == null) { - return x509Cert_ == null ? ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin)other); } else { - return x509CertBuilder_.getMessage(); + super.mergeFrom(other); + return this; } } - /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; - */ - public Builder setX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert value) { - if (x509CertBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - x509Cert_ = value; - onChanged(); - } else { - x509CertBuilder_.setMessage(value); + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance()) return this; + if (other.hasReshare()) { + setReshare(other.getReshare()); } - bitField0_ |= 0x00000002; + this.mergeUnknownFields(other.unknownFields); + onChanged(); return this; } - /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; - */ - public Builder setX509Cert( - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder builderForValue) { - if (x509CertBuilder_ == null) { - x509Cert_ = builderForValue.build(); - onChanged(); - } else { - x509CertBuilder_.setMessage(builderForValue.build()); + + @java.lang.Override + public final boolean isInitialized() { + if (!hasReshare()) { + return false; } - bitField0_ |= 0x00000002; - return this; + return true; } - /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; - */ - public Builder mergeX509Cert(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert value) { - if (x509CertBuilder_ == null) { - if (((bitField0_ & 0x00000002) != 0) && - x509Cert_ != null && - x509Cert_ != ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance()) { - x509Cert_ = - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.newBuilder(x509Cert_).mergeFrom(value).buildPartial(); - } else { - x509Cert_ = value; + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); } - onChanged(); - } else { - x509CertBuilder_.mergeFrom(value); } - bitField0_ |= 0x00000002; return this; } + private int bitField0_; + + private com.google.protobuf.ByteString reshare_ = com.google.protobuf.ByteString.EMPTY; /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; + * required bytes reshare = 1; */ - public Builder clearX509Cert() { - if (x509CertBuilder_ == null) { - x509Cert_ = null; - onChanged(); - } else { - x509CertBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); - return this; + public boolean hasReshare() { + return ((bitField0_ & 0x00000001) != 0); } /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; + * required bytes reshare = 1; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder getX509CertBuilder() { - bitField0_ |= 0x00000002; - onChanged(); - return getX509CertFieldBuilder().getBuilder(); + public com.google.protobuf.ByteString getReshare() { + return reshare_; } /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; + * required bytes reshare = 1; */ - public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder getX509CertOrBuilder() { - if (x509CertBuilder_ != null) { - return x509CertBuilder_.getMessageOrBuilder(); - } else { - return x509Cert_ == null ? - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance() : x509Cert_; - } + public Builder setReshare(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + reshare_ = value; + onChanged(); + return this; } /** - * optional .ocs.AuthReshareX509Cert x509cert = 2; + * required bytes reshare = 1; */ - private com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder> - getX509CertFieldBuilder() { - if (x509CertBuilder_ == null) { - x509CertBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder>( - getX509Cert(), - getParentForChildren(), - isClean()); - x509Cert_ = null; - } - return x509CertBuilder_; + public Builder clearReshare() { + bitField0_ = (bitField0_ & ~0x00000001); + reshare_ = getDefaultInstance().getReshare(); + onChanged(); + return this; } @java.lang.Override public final Builder setUnknownFields( @@ -10323,79 +15104,81 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.AuthReshare) + // @@protoc_insertion_point(builder_scope:ocs.AuthReshareByzCoin) } - // @@protoc_insertion_point(class_scope:ocs.AuthReshare) - private static final ch.epfl.dedis.lib.proto.OCS.AuthReshare DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthReshareByzCoin) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReshare(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin(); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshare getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public AuthReshare parsePartialFrom( + public AuthReshareByzCoin parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new AuthReshare(input, extensionRegistry); + return new AuthReshareByzCoin(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshare getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface AuthReshareByzCoinOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.AuthReshareByzCoin) + public interface AuthReshareX509CertOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.AuthReshareX509Cert) com.google.protobuf.MessageOrBuilder { /** - * required bytes reshare = 1; + * repeated bytes certificates = 1; */ - boolean hasReshare(); + java.util.List getCertificatesList(); /** - * required bytes reshare = 1; + * repeated bytes certificates = 1; */ - com.google.protobuf.ByteString getReshare(); + int getCertificatesCount(); + /** + * repeated bytes certificates = 1; + */ + com.google.protobuf.ByteString getCertificates(int index); } /** *
-   * AuthReshareByzCoin holds the byzcoin-proof that contains the latest OCS-instance
-   * which includes the roster. The OCS-nodes will make sure that the version of the
-   * OCS-instance is bigger than the current version.
+   * AuthReshareX509Cert holds the X509 proof that the new roster is valid.
    * 
* - * Protobuf type {@code ocs.AuthReshareByzCoin} + * Protobuf type {@code ocs.AuthReshareX509Cert} */ - public static final class AuthReshareByzCoin extends + public static final class AuthReshareX509Cert extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.AuthReshareByzCoin) - AuthReshareByzCoinOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.AuthReshareX509Cert) + AuthReshareX509CertOrBuilder { private static final long serialVersionUID = 0L; - // Use AuthReshareByzCoin.newBuilder() to construct. - private AuthReshareByzCoin(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use AuthReshareX509Cert.newBuilder() to construct. + private AuthReshareX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private AuthReshareByzCoin() { - reshare_ = com.google.protobuf.ByteString.EMPTY; + private AuthReshareX509Cert() { + certificates_ = java.util.Collections.emptyList(); } @java.lang.Override @@ -10403,7 +15186,7 @@ private AuthReshareByzCoin() { getUnknownFields() { return this.unknownFields; } - private AuthReshareByzCoin( + private AuthReshareX509Cert( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -10423,8 +15206,11 @@ private AuthReshareByzCoin( done = true; break; case 10: { - bitField0_ |= 0x00000001; - reshare_ = input.readBytes(); + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + certificates_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + certificates_.add(input.readBytes()); break; } default: { @@ -10442,37 +15228,46 @@ private AuthReshareByzCoin( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); // C + } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder.class); } - private int bitField0_; - public static final int RESHARE_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString reshare_; + public static final int CERTIFICATES_FIELD_NUMBER = 1; + private java.util.List certificates_; /** - * required bytes reshare = 1; + * repeated bytes certificates = 1; */ - public boolean hasReshare() { - return ((bitField0_ & 0x00000001) != 0); + public java.util.List + getCertificatesList() { + return certificates_; } /** - * required bytes reshare = 1; + * repeated bytes certificates = 1; */ - public com.google.protobuf.ByteString getReshare() { - return reshare_; + public int getCertificatesCount() { + return certificates_.size(); + } + /** + * repeated bytes certificates = 1; + */ + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); } private byte memoizedIsInitialized = -1; @@ -10482,10 +15277,6 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; - if (!hasReshare()) { - memoizedIsInitialized = 0; - return false; - } memoizedIsInitialized = 1; return true; } @@ -10493,8 +15284,8 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - if (((bitField0_ & 0x00000001) != 0)) { - output.writeBytes(1, reshare_); + for (int i = 0; i < certificates_.size(); i++) { + output.writeBytes(1, certificates_.get(i)); } unknownFields.writeTo(output); } @@ -10505,9 +15296,14 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - if (((bitField0_ & 0x00000001) != 0)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, reshare_); + { + int dataSize = 0; + for (int i = 0; i < certificates_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(certificates_.get(i)); + } + size += dataSize; + size += 1 * getCertificatesList().size(); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -10519,16 +15315,13 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin other = (ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin) obj; + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert other = (ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert) obj; - if (hasReshare() != other.hasReshare()) return false; - if (hasReshare()) { - if (!getReshare() - .equals(other.getReshare())) return false; - } + if (!getCertificatesList() + .equals(other.getCertificatesList())) return false; if (!unknownFields.equals(other.unknownFields)) return false; return true; } @@ -10540,78 +15333,78 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (hasReshare()) { - hash = (37 * hash) + RESHARE_FIELD_NUMBER; - hash = (53 * hash) + getReshare().hashCode(); + if (getCertificatesCount() > 0) { + hash = (37 * hash) + CERTIFICATES_FIELD_NUMBER; + hash = (53 * hash) + getCertificatesList().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -10624,7 +15417,7 @@ public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -10641,31 +15434,29 @@ protected Builder newBuilderForType( } /** *
-     * AuthReshareByzCoin holds the byzcoin-proof that contains the latest OCS-instance
-     * which includes the roster. The OCS-nodes will make sure that the version of the
-     * OCS-instance is bigger than the current version.
+     * AuthReshareX509Cert holds the X509 proof that the new roster is valid.
      * 
* - * Protobuf type {@code ocs.AuthReshareByzCoin} + * Protobuf type {@code ocs.AuthReshareX509Cert} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.AuthReshareByzCoin) - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoinOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.AuthReshareX509Cert) + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.Builder.class); + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder.class); } - // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.newBuilder() + // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -10683,7 +15474,7 @@ private void maybeForceBuilderInitialization() { @java.lang.Override public Builder clear() { super.clear(); - reshare_ = com.google.protobuf.ByteString.EMPTY; + certificates_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); return this; } @@ -10691,17 +15482,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareByzCoin_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_descriptor; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance(); } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin build() { - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin result = buildPartial(); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert build() { + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -10709,15 +15500,14 @@ public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin build() { } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin buildPartial() { - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin result = new ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin(this); + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert buildPartial() { + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert result = new ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert(this); int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) != 0)) { - to_bitField0_ |= 0x00000001; + if (((bitField0_ & 0x00000001) != 0)) { + certificates_ = java.util.Collections.unmodifiableList(certificates_); + bitField0_ = (bitField0_ & ~0x00000001); } - result.reshare_ = reshare_; - result.bitField0_ = to_bitField0_; + result.certificates_ = certificates_; onBuilt(); return result; } @@ -10756,18 +15546,25 @@ public Builder addRepeatedField( } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin)other); + if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin other) { - if (other == ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin.getDefaultInstance()) return this; - if (other.hasReshare()) { - setReshare(other.getReshare()); + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert other) { + if (other == ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance()) return this; + if (!other.certificates_.isEmpty()) { + if (certificates_.isEmpty()) { + certificates_ = other.certificates_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureCertificatesIsMutable(); + certificates_.addAll(other.certificates_); + } + onChanged(); } this.mergeUnknownFields(other.unknownFields); onChanged(); @@ -10776,9 +15573,6 @@ public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin other) { @java.lang.Override public final boolean isInitialized() { - if (!hasReshare()) { - return false; - } return true; } @@ -10787,11 +15581,11 @@ public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin parsedMessage = null; + ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin) e.getUnfinishedMessage(); + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -10802,37 +15596,75 @@ public Builder mergeFrom( } private int bitField0_; - private com.google.protobuf.ByteString reshare_ = com.google.protobuf.ByteString.EMPTY; + private java.util.List certificates_ = java.util.Collections.emptyList(); + private void ensureCertificatesIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + certificates_ = new java.util.ArrayList(certificates_); + bitField0_ |= 0x00000001; + } + } /** - * required bytes reshare = 1; + * repeated bytes certificates = 1; */ - public boolean hasReshare() { - return ((bitField0_ & 0x00000001) != 0); + public java.util.List + getCertificatesList() { + return ((bitField0_ & 0x00000001) != 0) ? + java.util.Collections.unmodifiableList(certificates_) : certificates_; } /** - * required bytes reshare = 1; + * repeated bytes certificates = 1; */ - public com.google.protobuf.ByteString getReshare() { - return reshare_; + public int getCertificatesCount() { + return certificates_.size(); } /** - * required bytes reshare = 1; + * repeated bytes certificates = 1; */ - public Builder setReshare(com.google.protobuf.ByteString value) { + public com.google.protobuf.ByteString getCertificates(int index) { + return certificates_.get(index); + } + /** + * repeated bytes certificates = 1; + */ + public Builder setCertificates( + int index, com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } - bitField0_ |= 0x00000001; - reshare_ = value; + ensureCertificatesIsMutable(); + certificates_.set(index, value); onChanged(); return this; } /** - * required bytes reshare = 1; + * repeated bytes certificates = 1; */ - public Builder clearReshare() { + public Builder addCertificates(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureCertificatesIsMutable(); + certificates_.add(value); + onChanged(); + return this; + } + /** + * repeated bytes certificates = 1; + */ + public Builder addAllCertificates( + java.lang.Iterable values) { + ensureCertificatesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, certificates_); + onChanged(); + return this; + } + /** + * repeated bytes certificates = 1; + */ + public Builder clearCertificates() { + certificates_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); - reshare_ = getDefaultInstance().getReshare(); onChanged(); return this; } @@ -10849,81 +15681,130 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.AuthReshareByzCoin) + // @@protoc_insertion_point(builder_scope:ocs.AuthReshareX509Cert) } - // @@protoc_insertion_point(class_scope:ocs.AuthReshareByzCoin) - private static final ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.AuthReshareX509Cert) + private static final ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert(); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public AuthReshareByzCoin parsePartialFrom( + public AuthReshareX509Cert parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new AuthReshareByzCoin(input, extensionRegistry); + return new AuthReshareX509Cert(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshareByzCoin getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } - public interface AuthReshareX509CertOrBuilder extends - // @@protoc_insertion_point(interface_extends:ocs.AuthReshareX509Cert) + public interface OCSProofOrBuilder extends + // @@protoc_insertion_point(interface_extends:ocs.OCSProof) com.google.protobuf.MessageOrBuilder { /** - * repeated bytes certificates = 1; + * required bytes ocsid = 1; */ - java.util.List getCertificatesList(); + boolean hasOcsid(); /** - * repeated bytes certificates = 1; + * required bytes ocsid = 1; */ - int getCertificatesCount(); + com.google.protobuf.ByteString getOcsid(); + /** - * repeated bytes certificates = 1; + * required .onet.Roster roster = 2; */ - com.google.protobuf.ByteString getCertificates(int index); + boolean hasRoster(); + /** + * required .onet.Roster roster = 2; + */ + ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster(); + /** + * required .onet.Roster roster = 2; + */ + ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder(); + + /** + * required .ocs.Policy policyreencrypt = 3; + */ + boolean hasPolicyreencrypt(); + /** + * required .ocs.Policy policyreencrypt = 3; + */ + ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt(); + /** + * required .ocs.Policy policyreencrypt = 3; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder(); + + /** + * required .ocs.Policy policyreshare = 4; + */ + boolean hasPolicyreshare(); + /** + * required .ocs.Policy policyreshare = 4; + */ + ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare(); + /** + * required .ocs.Policy policyreshare = 4; + */ + ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder(); + + /** + * repeated bytes signatures = 5; + */ + java.util.List getSignaturesList(); + /** + * repeated bytes signatures = 5; + */ + int getSignaturesCount(); + /** + * repeated bytes signatures = 5; + */ + com.google.protobuf.ByteString getSignatures(int index); } /** *
-   * AuthReshareX509Cert holds the X509 proof that the new roster is valid.
+   * OCSProof can be used to proof
    * 
* - * Protobuf type {@code ocs.AuthReshareX509Cert} + * Protobuf type {@code ocs.OCSProof} */ - public static final class AuthReshareX509Cert extends + public static final class OCSProof extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:ocs.AuthReshareX509Cert) - AuthReshareX509CertOrBuilder { + // @@protoc_insertion_point(message_implements:ocs.OCSProof) + OCSProofOrBuilder { private static final long serialVersionUID = 0L; - // Use AuthReshareX509Cert.newBuilder() to construct. - private AuthReshareX509Cert(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use OCSProof.newBuilder() to construct. + private OCSProof(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private AuthReshareX509Cert() { - certificates_ = java.util.Collections.emptyList(); + private OCSProof() { + ocsid_ = com.google.protobuf.ByteString.EMPTY; + signatures_ = java.util.Collections.emptyList(); } @java.lang.Override @@ -10931,7 +15812,7 @@ private AuthReshareX509Cert() { getUnknownFields() { return this.unknownFields; } - private AuthReshareX509Cert( + private OCSProof( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -10951,11 +15832,55 @@ private AuthReshareX509Cert( done = true; break; case 10: { - if (!((mutable_bitField0_ & 0x00000001) != 0)) { - certificates_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000001; + bitField0_ |= 0x00000001; + ocsid_ = input.readBytes(); + break; + } + case 18: { + ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) != 0)) { + subBuilder = roster_.toBuilder(); } - certificates_.add(input.readBytes()); + roster_ = input.readMessage(ch.epfl.dedis.lib.proto.OnetProto.Roster.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(roster_); + roster_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + case 26: { + ch.epfl.dedis.lib.proto.OCS.Policy.Builder subBuilder = null; + if (((bitField0_ & 0x00000004) != 0)) { + subBuilder = policyreencrypt_.toBuilder(); + } + policyreencrypt_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Policy.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(policyreencrypt_); + policyreencrypt_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000004; + break; + } + case 34: { + ch.epfl.dedis.lib.proto.OCS.Policy.Builder subBuilder = null; + if (((bitField0_ & 0x00000008) != 0)) { + subBuilder = policyreshare_.toBuilder(); + } + policyreshare_ = input.readMessage(ch.epfl.dedis.lib.proto.OCS.Policy.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(policyreshare_); + policyreshare_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000008; + break; + } + case 42: { + if (!((mutable_bitField0_ & 0x00000010) != 0)) { + signatures_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000010; + } + signatures_.add(input.readBytes()); break; } default: { @@ -10973,8 +15898,8 @@ private AuthReshareX509Cert( throw new com.google.protobuf.InvalidProtocolBufferException( e).setUnfinishedMessage(this); } finally { - if (((mutable_bitField0_ & 0x00000001) != 0)) { - certificates_ = java.util.Collections.unmodifiableList(certificates_); // C + if (((mutable_bitField0_ & 0x00000010) != 0)) { + signatures_ = java.util.Collections.unmodifiableList(signatures_); // C } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); @@ -10982,37 +15907,116 @@ private AuthReshareX509Cert( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_OCSProof_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_OCSProof_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder.class); + ch.epfl.dedis.lib.proto.OCS.OCSProof.class, ch.epfl.dedis.lib.proto.OCS.OCSProof.Builder.class); } - public static final int CERTIFICATES_FIELD_NUMBER = 1; - private java.util.List certificates_; + private int bitField0_; + public static final int OCSID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString ocsid_; /** - * repeated bytes certificates = 1; + * required bytes ocsid = 1; + */ + public boolean hasOcsid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes ocsid = 1; + */ + public com.google.protobuf.ByteString getOcsid() { + return ocsid_; + } + + public static final int ROSTER_FIELD_NUMBER = 2; + private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_; + /** + * required .onet.Roster roster = 2; + */ + public boolean hasRoster() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required .onet.Roster roster = 2; + */ + public ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster() { + return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; + } + /** + * required .onet.Roster roster = 2; + */ + public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() { + return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; + } + + public static final int POLICYREENCRYPT_FIELD_NUMBER = 3; + private ch.epfl.dedis.lib.proto.OCS.Policy policyreencrypt_; + /** + * required .ocs.Policy policyreencrypt = 3; + */ + public boolean hasPolicyreencrypt() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required .ocs.Policy policyreencrypt = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt() { + return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + } + /** + * required .ocs.Policy policyreencrypt = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder() { + return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + } + + public static final int POLICYRESHARE_FIELD_NUMBER = 4; + private ch.epfl.dedis.lib.proto.OCS.Policy policyreshare_; + /** + * required .ocs.Policy policyreshare = 4; + */ + public boolean hasPolicyreshare() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * required .ocs.Policy policyreshare = 4; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare() { + return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + } + /** + * required .ocs.Policy policyreshare = 4; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder() { + return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + } + + public static final int SIGNATURES_FIELD_NUMBER = 5; + private java.util.List signatures_; + /** + * repeated bytes signatures = 5; */ public java.util.List - getCertificatesList() { - return certificates_; + getSignaturesList() { + return signatures_; } /** - * repeated bytes certificates = 1; + * repeated bytes signatures = 5; */ - public int getCertificatesCount() { - return certificates_.size(); + public int getSignaturesCount() { + return signatures_.size(); } /** - * repeated bytes certificates = 1; + * repeated bytes signatures = 5; */ - public com.google.protobuf.ByteString getCertificates(int index) { - return certificates_.get(index); + public com.google.protobuf.ByteString getSignatures(int index) { + return signatures_.get(index); } private byte memoizedIsInitialized = -1; @@ -11022,6 +16026,34 @@ public final boolean isInitialized() { if (isInitialized == 1) return true; if (isInitialized == 0) return false; + if (!hasOcsid()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasRoster()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPolicyreencrypt()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasPolicyreshare()) { + memoizedIsInitialized = 0; + return false; + } + if (!getRoster().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getPolicyreencrypt().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + if (!getPolicyreshare().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } memoizedIsInitialized = 1; return true; } @@ -11029,8 +16061,20 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - for (int i = 0; i < certificates_.size(); i++) { - output.writeBytes(1, certificates_.get(i)); + if (((bitField0_ & 0x00000001) != 0)) { + output.writeBytes(1, ocsid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getRoster()); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeMessage(3, getPolicyreencrypt()); + } + if (((bitField0_ & 0x00000008) != 0)) { + output.writeMessage(4, getPolicyreshare()); + } + for (int i = 0; i < signatures_.size(); i++) { + output.writeBytes(5, signatures_.get(i)); } unknownFields.writeTo(output); } @@ -11041,14 +16085,30 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, ocsid_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getRoster()); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, getPolicyreencrypt()); + } + if (((bitField0_ & 0x00000008) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, getPolicyreshare()); + } { int dataSize = 0; - for (int i = 0; i < certificates_.size(); i++) { + for (int i = 0; i < signatures_.size(); i++) { dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(certificates_.get(i)); + .computeBytesSizeNoTag(signatures_.get(i)); } size += dataSize; - size += 1 * getCertificatesList().size(); + size += 1 * getSignaturesList().size(); } size += unknownFields.getSerializedSize(); memoizedSize = size; @@ -11060,13 +16120,33 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert)) { + if (!(obj instanceof ch.epfl.dedis.lib.proto.OCS.OCSProof)) { return super.equals(obj); } - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert other = (ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert) obj; - - if (!getCertificatesList() - .equals(other.getCertificatesList())) return false; + ch.epfl.dedis.lib.proto.OCS.OCSProof other = (ch.epfl.dedis.lib.proto.OCS.OCSProof) obj; + + if (hasOcsid() != other.hasOcsid()) return false; + if (hasOcsid()) { + if (!getOcsid() + .equals(other.getOcsid())) return false; + } + if (hasRoster() != other.hasRoster()) return false; + if (hasRoster()) { + if (!getRoster() + .equals(other.getRoster())) return false; + } + if (hasPolicyreencrypt() != other.hasPolicyreencrypt()) return false; + if (hasPolicyreencrypt()) { + if (!getPolicyreencrypt() + .equals(other.getPolicyreencrypt())) return false; + } + if (hasPolicyreshare() != other.hasPolicyreshare()) return false; + if (hasPolicyreshare()) { + if (!getPolicyreshare() + .equals(other.getPolicyreshare())) return false; + } + if (!getSignaturesList() + .equals(other.getSignaturesList())) return false; if (!unknownFields.equals(other.unknownFields)) return false; return true; } @@ -11078,78 +16158,94 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - if (getCertificatesCount() > 0) { - hash = (37 * hash) + CERTIFICATES_FIELD_NUMBER; - hash = (53 * hash) + getCertificatesList().hashCode(); + if (hasOcsid()) { + hash = (37 * hash) + OCSID_FIELD_NUMBER; + hash = (53 * hash) + getOcsid().hashCode(); + } + if (hasRoster()) { + hash = (37 * hash) + ROSTER_FIELD_NUMBER; + hash = (53 * hash) + getRoster().hashCode(); + } + if (hasPolicyreencrypt()) { + hash = (37 * hash) + POLICYREENCRYPT_FIELD_NUMBER; + hash = (53 * hash) + getPolicyreencrypt().hashCode(); + } + if (hasPolicyreshare()) { + hash = (37 * hash) + POLICYRESHARE_FIELD_NUMBER; + hash = (53 * hash) + getPolicyreshare().hashCode(); + } + if (getSignaturesCount() > 0) { + hash = (37 * hash) + SIGNATURES_FIELD_NUMBER; + hash = (53 * hash) + getSignaturesList().hashCode(); } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom(byte[] data) + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseDelimitedFrom(java.io.InputStream input) + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseDelimitedFrom( + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( + public static ch.epfl.dedis.lib.proto.OCS.OCSProof parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -11162,7 +16258,7 @@ public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parseFrom( public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert prototype) { + public static Builder newBuilder(ch.epfl.dedis.lib.proto.OCS.OCSProof prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -11179,237 +16275,712 @@ protected Builder newBuilderForType( } /** *
-     * AuthReshareX509Cert holds the X509 proof that the new roster is valid.
+     * OCSProof can be used to proof
      * 
* - * Protobuf type {@code ocs.AuthReshareX509Cert} + * Protobuf type {@code ocs.OCSProof} */ public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:ocs.AuthReshareX509Cert) - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509CertOrBuilder { + // @@protoc_insertion_point(builder_implements:ocs.OCSProof) + ch.epfl.dedis.lib.proto.OCS.OCSProofOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_descriptor; + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_OCSProof_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_fieldAccessorTable + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_OCSProof_fieldAccessorTable .ensureFieldAccessorsInitialized( - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.class, ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.Builder.class); + ch.epfl.dedis.lib.proto.OCS.OCSProof.class, ch.epfl.dedis.lib.proto.OCS.OCSProof.Builder.class); + } + + // Construct using ch.epfl.dedis.lib.proto.OCS.OCSProof.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getRosterFieldBuilder(); + getPolicyreencryptFieldBuilder(); + getPolicyreshareFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + ocsid_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + if (rosterBuilder_ == null) { + roster_ = null; + } else { + rosterBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + if (policyreencryptBuilder_ == null) { + policyreencrypt_ = null; + } else { + policyreencryptBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + if (policyreshareBuilder_ == null) { + policyreshare_ = null; + } else { + policyreshareBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + signatures_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000010); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_OCSProof_descriptor; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.OCSProof getDefaultInstanceForType() { + return ch.epfl.dedis.lib.proto.OCS.OCSProof.getDefaultInstance(); + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.OCSProof build() { + ch.epfl.dedis.lib.proto.OCS.OCSProof result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public ch.epfl.dedis.lib.proto.OCS.OCSProof buildPartial() { + ch.epfl.dedis.lib.proto.OCS.OCSProof result = new ch.epfl.dedis.lib.proto.OCS.OCSProof(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.ocsid_ = ocsid_; + if (((from_bitField0_ & 0x00000002) != 0)) { + if (rosterBuilder_ == null) { + result.roster_ = roster_; + } else { + result.roster_ = rosterBuilder_.build(); + } + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + if (policyreencryptBuilder_ == null) { + result.policyreencrypt_ = policyreencrypt_; + } else { + result.policyreencrypt_ = policyreencryptBuilder_.build(); + } + to_bitField0_ |= 0x00000004; + } + if (((from_bitField0_ & 0x00000008) != 0)) { + if (policyreshareBuilder_ == null) { + result.policyreshare_ = policyreshare_; + } else { + result.policyreshare_ = policyreshareBuilder_.build(); + } + to_bitField0_ |= 0x00000008; + } + if (((bitField0_ & 0x00000010) != 0)) { + signatures_ = java.util.Collections.unmodifiableList(signatures_); + bitField0_ = (bitField0_ & ~0x00000010); + } + result.signatures_ = signatures_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof ch.epfl.dedis.lib.proto.OCS.OCSProof) { + return mergeFrom((ch.epfl.dedis.lib.proto.OCS.OCSProof)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.OCSProof other) { + if (other == ch.epfl.dedis.lib.proto.OCS.OCSProof.getDefaultInstance()) return this; + if (other.hasOcsid()) { + setOcsid(other.getOcsid()); + } + if (other.hasRoster()) { + mergeRoster(other.getRoster()); + } + if (other.hasPolicyreencrypt()) { + mergePolicyreencrypt(other.getPolicyreencrypt()); + } + if (other.hasPolicyreshare()) { + mergePolicyreshare(other.getPolicyreshare()); + } + if (!other.signatures_.isEmpty()) { + if (signatures_.isEmpty()) { + signatures_ = other.signatures_; + bitField0_ = (bitField0_ & ~0x00000010); + } else { + ensureSignaturesIsMutable(); + signatures_.addAll(other.signatures_); + } + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasOcsid()) { + return false; + } + if (!hasRoster()) { + return false; + } + if (!hasPolicyreencrypt()) { + return false; + } + if (!hasPolicyreshare()) { + return false; + } + if (!getRoster().isInitialized()) { + return false; + } + if (!getPolicyreencrypt().isInitialized()) { + return false; + } + if (!getPolicyreshare().isInitialized()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + ch.epfl.dedis.lib.proto.OCS.OCSProof parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (ch.epfl.dedis.lib.proto.OCS.OCSProof) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString ocsid_ = com.google.protobuf.ByteString.EMPTY; + /** + * required bytes ocsid = 1; + */ + public boolean hasOcsid() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required bytes ocsid = 1; + */ + public com.google.protobuf.ByteString getOcsid() { + return ocsid_; + } + /** + * required bytes ocsid = 1; + */ + public Builder setOcsid(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + ocsid_ = value; + onChanged(); + return this; + } + /** + * required bytes ocsid = 1; + */ + public Builder clearOcsid() { + bitField0_ = (bitField0_ & ~0x00000001); + ocsid_ = getDefaultInstance().getOcsid(); + onChanged(); + return this; } - // Construct using ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); + private ch.epfl.dedis.lib.proto.OnetProto.Roster roster_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> rosterBuilder_; + /** + * required .onet.Roster roster = 2; + */ + public boolean hasRoster() { + return ((bitField0_ & 0x00000002) != 0); } - - private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); + /** + * required .onet.Roster roster = 2; + */ + public ch.epfl.dedis.lib.proto.OnetProto.Roster getRoster() { + if (rosterBuilder_ == null) { + return roster_ == null ? ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; + } else { + return rosterBuilder_.getMessage(); + } } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { + /** + * required .onet.Roster roster = 2; + */ + public Builder setRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { + if (rosterBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + roster_ = value; + onChanged(); + } else { + rosterBuilder_.setMessage(value); } + bitField0_ |= 0x00000002; + return this; } - @java.lang.Override - public Builder clear() { - super.clear(); - certificates_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000001); + /** + * required .onet.Roster roster = 2; + */ + public Builder setRoster( + ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder builderForValue) { + if (rosterBuilder_ == null) { + roster_ = builderForValue.build(); + onChanged(); + } else { + rosterBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; return this; } - - @java.lang.Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return ch.epfl.dedis.lib.proto.OCS.internal_static_ocs_AuthReshareX509Cert_descriptor; + /** + * required .onet.Roster roster = 2; + */ + public Builder mergeRoster(ch.epfl.dedis.lib.proto.OnetProto.Roster value) { + if (rosterBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + roster_ != null && + roster_ != ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance()) { + roster_ = + ch.epfl.dedis.lib.proto.OnetProto.Roster.newBuilder(roster_).mergeFrom(value).buildPartial(); + } else { + roster_ = value; + } + onChanged(); + } else { + rosterBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstanceForType() { - return ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance(); + /** + * required .onet.Roster roster = 2; + */ + public Builder clearRoster() { + if (rosterBuilder_ == null) { + roster_ = null; + onChanged(); + } else { + rosterBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert build() { - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); + /** + * required .onet.Roster roster = 2; + */ + public ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder getRosterBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getRosterFieldBuilder().getBuilder(); + } + /** + * required .onet.Roster roster = 2; + */ + public ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder getRosterOrBuilder() { + if (rosterBuilder_ != null) { + return rosterBuilder_.getMessageOrBuilder(); + } else { + return roster_ == null ? + ch.epfl.dedis.lib.proto.OnetProto.Roster.getDefaultInstance() : roster_; } - return result; } - - @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert buildPartial() { - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert result = new ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert(this); - int from_bitField0_ = bitField0_; - if (((bitField0_ & 0x00000001) != 0)) { - certificates_ = java.util.Collections.unmodifiableList(certificates_); - bitField0_ = (bitField0_ & ~0x00000001); + /** + * required .onet.Roster roster = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder> + getRosterFieldBuilder() { + if (rosterBuilder_ == null) { + rosterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OnetProto.Roster, ch.epfl.dedis.lib.proto.OnetProto.Roster.Builder, ch.epfl.dedis.lib.proto.OnetProto.RosterOrBuilder>( + getRoster(), + getParentForChildren(), + isClean()); + roster_ = null; } - result.certificates_ = certificates_; - onBuilt(); - return result; + return rosterBuilder_; } - @java.lang.Override - public Builder clone() { - return super.clone(); + private ch.epfl.dedis.lib.proto.OCS.Policy policyreencrypt_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> policyreencryptBuilder_; + /** + * required .ocs.Policy policyreencrypt = 3; + */ + public boolean hasPolicyreencrypt() { + return ((bitField0_ & 0x00000004) != 0); } - @java.lang.Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.setField(field, value); + /** + * required .ocs.Policy policyreencrypt = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreencrypt() { + if (policyreencryptBuilder_ == null) { + return policyreencrypt_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + } else { + return policyreencryptBuilder_.getMessage(); + } } - @java.lang.Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return super.clearField(field); + /** + * required .ocs.Policy policyreencrypt = 3; + */ + public Builder setPolicyreencrypt(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreencryptBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + policyreencrypt_ = value; + onChanged(); + } else { + policyreencryptBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .ocs.Policy policyreencrypt = 3; + */ + public Builder setPolicyreencrypt( + ch.epfl.dedis.lib.proto.OCS.Policy.Builder builderForValue) { + if (policyreencryptBuilder_ == null) { + policyreencrypt_ = builderForValue.build(); + onChanged(); + } else { + policyreencryptBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .ocs.Policy policyreencrypt = 3; + */ + public Builder mergePolicyreencrypt(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreencryptBuilder_ == null) { + if (((bitField0_ & 0x00000004) != 0) && + policyreencrypt_ != null && + policyreencrypt_ != ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) { + policyreencrypt_ = + ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder(policyreencrypt_).mergeFrom(value).buildPartial(); + } else { + policyreencrypt_ = value; + } + onChanged(); + } else { + policyreencryptBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + return this; + } + /** + * required .ocs.Policy policyreencrypt = 3; + */ + public Builder clearPolicyreencrypt() { + if (policyreencryptBuilder_ == null) { + policyreencrypt_ = null; + onChanged(); + } else { + policyreencryptBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + /** + * required .ocs.Policy policyreencrypt = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy.Builder getPolicyreencryptBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getPolicyreencryptFieldBuilder().getBuilder(); + } + /** + * required .ocs.Policy policyreencrypt = 3; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreencryptOrBuilder() { + if (policyreencryptBuilder_ != null) { + return policyreencryptBuilder_.getMessageOrBuilder(); + } else { + return policyreencrypt_ == null ? + ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreencrypt_; + } + } + /** + * required .ocs.Policy policyreencrypt = 3; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> + getPolicyreencryptFieldBuilder() { + if (policyreencryptBuilder_ == null) { + policyreencryptBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder>( + getPolicyreencrypt(), + getParentForChildren(), + isClean()); + policyreencrypt_ = null; + } + return policyreencryptBuilder_; } - @java.lang.Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return super.clearOneof(oneof); + + private ch.epfl.dedis.lib.proto.OCS.Policy policyreshare_; + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> policyreshareBuilder_; + /** + * required .ocs.Policy policyreshare = 4; + */ + public boolean hasPolicyreshare() { + return ((bitField0_ & 0x00000008) != 0); } - @java.lang.Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { - return super.setRepeatedField(field, index, value); + /** + * required .ocs.Policy policyreshare = 4; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy getPolicyreshare() { + if (policyreshareBuilder_ == null) { + return policyreshare_ == null ? ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + } else { + return policyreshareBuilder_.getMessage(); + } } - @java.lang.Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { - return super.addRepeatedField(field, value); + /** + * required .ocs.Policy policyreshare = 4; + */ + public Builder setPolicyreshare(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreshareBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + policyreshare_ = value; + onChanged(); + } else { + policyreshareBuilder_.setMessage(value); + } + bitField0_ |= 0x00000008; + return this; } - @java.lang.Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert) { - return mergeFrom((ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert)other); + /** + * required .ocs.Policy policyreshare = 4; + */ + public Builder setPolicyreshare( + ch.epfl.dedis.lib.proto.OCS.Policy.Builder builderForValue) { + if (policyreshareBuilder_ == null) { + policyreshare_ = builderForValue.build(); + onChanged(); } else { - super.mergeFrom(other); - return this; + policyreshareBuilder_.setMessage(builderForValue.build()); } + bitField0_ |= 0x00000008; + return this; } - - public Builder mergeFrom(ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert other) { - if (other == ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert.getDefaultInstance()) return this; - if (!other.certificates_.isEmpty()) { - if (certificates_.isEmpty()) { - certificates_ = other.certificates_; - bitField0_ = (bitField0_ & ~0x00000001); + /** + * required .ocs.Policy policyreshare = 4; + */ + public Builder mergePolicyreshare(ch.epfl.dedis.lib.proto.OCS.Policy value) { + if (policyreshareBuilder_ == null) { + if (((bitField0_ & 0x00000008) != 0) && + policyreshare_ != null && + policyreshare_ != ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance()) { + policyreshare_ = + ch.epfl.dedis.lib.proto.OCS.Policy.newBuilder(policyreshare_).mergeFrom(value).buildPartial(); } else { - ensureCertificatesIsMutable(); - certificates_.addAll(other.certificates_); + policyreshare_ = value; } onChanged(); + } else { + policyreshareBuilder_.mergeFrom(value); } - this.mergeUnknownFields(other.unknownFields); - onChanged(); + bitField0_ |= 0x00000008; return this; } - - @java.lang.Override - public final boolean isInitialized() { - return true; - } - - @java.lang.Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } + /** + * required .ocs.Policy policyreshare = 4; + */ + public Builder clearPolicyreshare() { + if (policyreshareBuilder_ == null) { + policyreshare_ = null; + onChanged(); + } else { + policyreshareBuilder_.clear(); } + bitField0_ = (bitField0_ & ~0x00000008); return this; } - private int bitField0_; + /** + * required .ocs.Policy policyreshare = 4; + */ + public ch.epfl.dedis.lib.proto.OCS.Policy.Builder getPolicyreshareBuilder() { + bitField0_ |= 0x00000008; + onChanged(); + return getPolicyreshareFieldBuilder().getBuilder(); + } + /** + * required .ocs.Policy policyreshare = 4; + */ + public ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder getPolicyreshareOrBuilder() { + if (policyreshareBuilder_ != null) { + return policyreshareBuilder_.getMessageOrBuilder(); + } else { + return policyreshare_ == null ? + ch.epfl.dedis.lib.proto.OCS.Policy.getDefaultInstance() : policyreshare_; + } + } + /** + * required .ocs.Policy policyreshare = 4; + */ + private com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder> + getPolicyreshareFieldBuilder() { + if (policyreshareBuilder_ == null) { + policyreshareBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + ch.epfl.dedis.lib.proto.OCS.Policy, ch.epfl.dedis.lib.proto.OCS.Policy.Builder, ch.epfl.dedis.lib.proto.OCS.PolicyOrBuilder>( + getPolicyreshare(), + getParentForChildren(), + isClean()); + policyreshare_ = null; + } + return policyreshareBuilder_; + } - private java.util.List certificates_ = java.util.Collections.emptyList(); - private void ensureCertificatesIsMutable() { - if (!((bitField0_ & 0x00000001) != 0)) { - certificates_ = new java.util.ArrayList(certificates_); - bitField0_ |= 0x00000001; + private java.util.List signatures_ = java.util.Collections.emptyList(); + private void ensureSignaturesIsMutable() { + if (!((bitField0_ & 0x00000010) != 0)) { + signatures_ = new java.util.ArrayList(signatures_); + bitField0_ |= 0x00000010; } } /** - * repeated bytes certificates = 1; + * repeated bytes signatures = 5; */ public java.util.List - getCertificatesList() { - return ((bitField0_ & 0x00000001) != 0) ? - java.util.Collections.unmodifiableList(certificates_) : certificates_; + getSignaturesList() { + return ((bitField0_ & 0x00000010) != 0) ? + java.util.Collections.unmodifiableList(signatures_) : signatures_; } /** - * repeated bytes certificates = 1; + * repeated bytes signatures = 5; */ - public int getCertificatesCount() { - return certificates_.size(); + public int getSignaturesCount() { + return signatures_.size(); } /** - * repeated bytes certificates = 1; + * repeated bytes signatures = 5; */ - public com.google.protobuf.ByteString getCertificates(int index) { - return certificates_.get(index); + public com.google.protobuf.ByteString getSignatures(int index) { + return signatures_.get(index); } /** - * repeated bytes certificates = 1; + * repeated bytes signatures = 5; */ - public Builder setCertificates( + public Builder setSignatures( int index, com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } - ensureCertificatesIsMutable(); - certificates_.set(index, value); + ensureSignaturesIsMutable(); + signatures_.set(index, value); onChanged(); return this; } /** - * repeated bytes certificates = 1; + * repeated bytes signatures = 5; */ - public Builder addCertificates(com.google.protobuf.ByteString value) { + public Builder addSignatures(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } - ensureCertificatesIsMutable(); - certificates_.add(value); + ensureSignaturesIsMutable(); + signatures_.add(value); onChanged(); return this; } /** - * repeated bytes certificates = 1; + * repeated bytes signatures = 5; */ - public Builder addAllCertificates( + public Builder addAllSignatures( java.lang.Iterable values) { - ensureCertificatesIsMutable(); + ensureSignaturesIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, certificates_); + values, signatures_); onChanged(); return this; } /** - * repeated bytes certificates = 1; + * repeated bytes signatures = 5; */ - public Builder clearCertificates() { - certificates_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000001); + public Builder clearSignatures() { + signatures_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000010); onChanged(); return this; } @@ -11426,46 +16997,56 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:ocs.AuthReshareX509Cert) + // @@protoc_insertion_point(builder_scope:ocs.OCSProof) } - // @@protoc_insertion_point(class_scope:ocs.AuthReshareX509Cert) - private static final ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:ocs.OCSProof) + private static final ch.epfl.dedis.lib.proto.OCS.OCSProof DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert(); + DEFAULT_INSTANCE = new ch.epfl.dedis.lib.proto.OCS.OCSProof(); } - public static ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstance() { + public static ch.epfl.dedis.lib.proto.OCS.OCSProof getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public AuthReshareX509Cert parsePartialFrom( + public OCSProof parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new AuthReshareX509Cert(input, extensionRegistry); + return new OCSProof(input, extensionRegistry); } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstanceForType() { + public ch.epfl.dedis.lib.proto.OCS.OCSProof getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AddPolicyCreateOCS_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AddPolicyCreateOCS_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AddPolicyCreateOCSReply_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AddPolicyCreateOCSReply_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor internal_static_ocs_CreateOCS_descriptor; private static final @@ -11476,6 +17057,16 @@ public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstanceForType private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_ocs_CreateOCSReply_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_GetProof_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_GetProof_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_GetProofReply_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_GetProofReply_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor internal_static_ocs_Reencrypt_descriptor; private static final @@ -11496,11 +17087,6 @@ public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstanceForType private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_ocs_ReshareReply_fieldAccessorTable; - private static final com.google.protobuf.Descriptors.Descriptor - internal_static_ocs_PolicyOCS_descriptor; - private static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_ocs_PolicyOCS_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor internal_static_ocs_Policy_descriptor; private static final @@ -11516,6 +17102,21 @@ public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstanceForType private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_ocs_PolicyX509Cert_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AuthCreate_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AuthCreate_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AuthCreateByzcoin_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AuthCreateByzcoin_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_AuthCreateX509Cert_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_AuthCreateX509Cert_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor internal_static_ocs_AuthReencrypt_descriptor; private static final @@ -11546,6 +17147,11 @@ public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstanceForType private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_ocs_AuthReshareX509Cert_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_ocs_OCSProof_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_ocs_OCSProof_fieldAccessorTable; public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { @@ -11555,33 +17161,47 @@ public ch.epfl.dedis.lib.proto.OCS.AuthReshareX509Cert getDefaultInstanceForType descriptor; static { java.lang.String[] descriptorData = { - "\n\tocs.proto\022\003ocs\032\nonet.proto\"F\n\tCreateOC" + - "S\022\034\n\006roster\030\001 \002(\0132\014.onet.Roster\022\033\n\006polic" + - "y\030\002 \002(\0132\013.ocs.Policy\"(\n\016CreateOCSReply\022\t" + - "\n\001x\030\001 \002(\014\022\013\n\003sig\030\002 \002(\014\"8\n\tReencrypt\022\t\n\001x" + - "\030\001 \002(\014\022 \n\004auth\030\002 \002(\0132\022.ocs.AuthReencrypt" + - "\"\036\n\016ReencryptReply\022\014\n\004xhat\030\001 \002(\014\"U\n\007Resh" + - "are\022\t\n\001x\030\001 \002(\014\022\037\n\tnewroster\030\002 \002(\0132\014.onet" + - ".Roster\022\036\n\004auth\030\003 \002(\0132\020.ocs.AuthReshare\"" + - "\033\n\014ReshareReply\022\013\n\003sig\030\001 \002(\014\"U\n\tPolicyOC" + - "S\022$\n\017policyreencrypt\030\001 \002(\0132\013.ocs.Policy\022" + - "\"\n\rpolicyreshare\030\002 \002(\0132\013.ocs.Policy\"X\n\006P" + - "olicy\022#\n\007byzcoin\030\001 \001(\0132\022.ocs.PolicyByzCo" + - "in\022)\n\014authx509cert\030\002 \001(\0132\023.ocs.PolicyX50" + - "9Cert\"/\n\rPolicyByzCoin\022\021\n\tbyzcoinid\030\001 \002(" + - "\014\022\013\n\003ttl\030\002 \002(\004\"/\n\016PolicyX509Cert\022\n\n\002ca\030\001" + - " \003(\014\022\021\n\tthreshold\030\002 \002(\021\"i\n\rAuthReencrypt" + - "\022*\n\007byzcoin\030\001 \001(\0132\031.ocs.AuthReencryptByz" + - "Coin\022,\n\010x509cert\030\002 \001(\0132\032.ocs.AuthReencry" + - "ptX509Cert\"3\n\024AuthReencryptByzCoin\022\r\n\005wr" + - "ite\030\001 \002(\014\022\014\n\004read\030\002 \002(\014\"=\n\025AuthReencrypt" + - "X509Cert\022\016\n\006secret\030\001 \002(\014\022\024\n\014certificates" + - "\030\002 \003(\014\"c\n\013AuthReshare\022(\n\007byzcoin\030\001 \001(\0132\027" + - ".ocs.AuthReshareByzCoin\022*\n\010x509cert\030\002 \001(" + - "\0132\030.ocs.AuthReshareX509Cert\"%\n\022AuthResha" + - "reByzCoin\022\017\n\007reshare\030\001 \002(\014\"+\n\023AuthReshar" + - "eX509Cert\022\024\n\014certificates\030\001 \003(\014B\036\n\027ch.ep" + - "fl.dedis.lib.protoB\003OCS" + "\n\tocs.proto\022\003ocs\032\nonet.proto\032\ndarc.proto" + + "\"1\n\022AddPolicyCreateOCS\022\033\n\006create\030\001 \002(\0132\013" + + ".ocs.Policy\"\031\n\027AddPolicyCreateOCSReply\"s" + + "\n\tCreateOCS\022\034\n\006roster\030\001 \002(\0132\014.onet.Roste" + + "r\022$\n\017policyreencrypt\030\002 \002(\0132\013.ocs.Policy\022" + + "\"\n\rpolicyreshare\030\003 \002(\0132\013.ocs.Policy\"\037\n\016C" + + "reateOCSReply\022\r\n\005ocsid\030\001 \002(\014\"\031\n\010GetProof" + + "\022\r\n\005ocsid\030\001 \002(\014\"-\n\rGetProofReply\022\034\n\005proo" + + "f\030\001 \002(\0132\r.ocs.OCSProof\"<\n\tReencrypt\022\r\n\005o" + + "csid\030\001 \002(\014\022 \n\004auth\030\002 \002(\0132\022.ocs.AuthReenc" + + "rypt\"7\n\016ReencryptReply\022\t\n\001x\030\001 \002(\014\022\017\n\007xha" + + "tenc\030\002 \002(\014\022\t\n\001c\030\003 \002(\014\"Y\n\007Reshare\022\r\n\005ocsi" + + "d\030\001 \002(\014\022\037\n\tnewroster\030\002 \002(\0132\014.onet.Roster" + + "\022\036\n\004auth\030\003 \002(\0132\020.ocs.AuthReshare\"\033\n\014Resh" + + "areReply\022\013\n\003sig\030\001 \002(\014\"T\n\006Policy\022#\n\007byzco" + + "in\030\001 \001(\0132\022.ocs.PolicyByzCoin\022%\n\010x509cert" + + "\030\002 \001(\0132\023.ocs.PolicyX509Cert\"/\n\rPolicyByz" + + "Coin\022\021\n\tbyzcoinid\030\001 \002(\014\022\013\n\003ttl\030\002 \002(\004\"/\n\016" + + "PolicyX509Cert\022\n\n\002ca\030\001 \003(\014\022\021\n\tthreshold\030" + + "\002 \002(\021\"`\n\nAuthCreate\022\'\n\007byzcoin\030\001 \002(\0132\026.o" + + "cs.AuthCreateByzcoin\022)\n\010x509cert\030\002 \002(\0132\027" + + ".ocs.AuthCreateX509Cert\";\n\021AuthCreateByz" + + "coin\022\021\n\tbyzcoinid\030\001 \002(\014\022\023\n\013ltsinstance\030\002" + + " \002(\014\"*\n\022AuthCreateX509Cert\022\024\n\014certificat" + + "es\030\001 \003(\014\"|\n\rAuthReencrypt\022\021\n\tephemeral\030\001" + + " \002(\014\022*\n\007byzcoin\030\002 \001(\0132\031.ocs.AuthReencryp" + + "tByzCoin\022,\n\010x509cert\030\003 \001(\0132\032.ocs.AuthRee" + + "ncryptX509Cert\"j\n\024AuthReencryptByzCoin\022\r" + + "\n\005write\030\001 \002(\014\022\014\n\004read\030\002 \002(\014\022\021\n\tephemeral" + + "\030\003 \002(\014\022\"\n\tsignature\030\004 \001(\0132\017.darc.Signatu" + + "re\"8\n\025AuthReencryptX509Cert\022\t\n\001u\030\001 \002(\014\022\024" + + "\n\014certificates\030\002 \003(\014\"c\n\013AuthReshare\022(\n\007b" + + "yzcoin\030\001 \001(\0132\027.ocs.AuthReshareByzCoin\022*\n" + + "\010x509cert\030\002 \001(\0132\030.ocs.AuthReshareX509Cer" + + "t\"%\n\022AuthReshareByzCoin\022\017\n\007reshare\030\001 \002(\014" + + "\"+\n\023AuthReshareX509Cert\022\024\n\014certificates\030" + + "\001 \003(\014\"\225\001\n\010OCSProof\022\r\n\005ocsid\030\001 \002(\014\022\034\n\006ros" + + "ter\030\002 \002(\0132\014.onet.Roster\022$\n\017policyreencry" + + "pt\030\003 \002(\0132\013.ocs.Policy\022\"\n\rpolicyreshare\030\004" + + " \002(\0132\013.ocs.Policy\022\022\n\nsignatures\030\005 \003(\014B\036\n" + + "\027ch.epfl.dedis.lib.protoB\003OCS" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { @@ -11595,104 +17215,148 @@ public com.google.protobuf.ExtensionRegistry assignDescriptors( .internalBuildGeneratedFileFrom(descriptorData, new com.google.protobuf.Descriptors.FileDescriptor[] { ch.epfl.dedis.lib.proto.OnetProto.getDescriptor(), + ch.epfl.dedis.lib.proto.DarcProto.getDescriptor(), }, assigner); - internal_static_ocs_CreateOCS_descriptor = + internal_static_ocs_AddPolicyCreateOCS_descriptor = getDescriptor().getMessageTypes().get(0); + internal_static_ocs_AddPolicyCreateOCS_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AddPolicyCreateOCS_descriptor, + new java.lang.String[] { "Create", }); + internal_static_ocs_AddPolicyCreateOCSReply_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_ocs_AddPolicyCreateOCSReply_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AddPolicyCreateOCSReply_descriptor, + new java.lang.String[] { }); + internal_static_ocs_CreateOCS_descriptor = + getDescriptor().getMessageTypes().get(2); internal_static_ocs_CreateOCS_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_CreateOCS_descriptor, - new java.lang.String[] { "Roster", "Policy", }); + new java.lang.String[] { "Roster", "Policyreencrypt", "Policyreshare", }); internal_static_ocs_CreateOCSReply_descriptor = - getDescriptor().getMessageTypes().get(1); + getDescriptor().getMessageTypes().get(3); internal_static_ocs_CreateOCSReply_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_CreateOCSReply_descriptor, - new java.lang.String[] { "X", "Sig", }); + new java.lang.String[] { "Ocsid", }); + internal_static_ocs_GetProof_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_ocs_GetProof_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_GetProof_descriptor, + new java.lang.String[] { "Ocsid", }); + internal_static_ocs_GetProofReply_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_ocs_GetProofReply_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_GetProofReply_descriptor, + new java.lang.String[] { "Proof", }); internal_static_ocs_Reencrypt_descriptor = - getDescriptor().getMessageTypes().get(2); + getDescriptor().getMessageTypes().get(6); internal_static_ocs_Reencrypt_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_Reencrypt_descriptor, - new java.lang.String[] { "X", "Auth", }); + new java.lang.String[] { "Ocsid", "Auth", }); internal_static_ocs_ReencryptReply_descriptor = - getDescriptor().getMessageTypes().get(3); + getDescriptor().getMessageTypes().get(7); internal_static_ocs_ReencryptReply_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_ReencryptReply_descriptor, - new java.lang.String[] { "Xhat", }); + new java.lang.String[] { "X", "Xhatenc", "C", }); internal_static_ocs_Reshare_descriptor = - getDescriptor().getMessageTypes().get(4); + getDescriptor().getMessageTypes().get(8); internal_static_ocs_Reshare_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_Reshare_descriptor, - new java.lang.String[] { "X", "Newroster", "Auth", }); + new java.lang.String[] { "Ocsid", "Newroster", "Auth", }); internal_static_ocs_ReshareReply_descriptor = - getDescriptor().getMessageTypes().get(5); + getDescriptor().getMessageTypes().get(9); internal_static_ocs_ReshareReply_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_ReshareReply_descriptor, new java.lang.String[] { "Sig", }); - internal_static_ocs_PolicyOCS_descriptor = - getDescriptor().getMessageTypes().get(6); - internal_static_ocs_PolicyOCS_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_ocs_PolicyOCS_descriptor, - new java.lang.String[] { "Policyreencrypt", "Policyreshare", }); internal_static_ocs_Policy_descriptor = - getDescriptor().getMessageTypes().get(7); + getDescriptor().getMessageTypes().get(10); internal_static_ocs_Policy_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_Policy_descriptor, - new java.lang.String[] { "Byzcoin", "Authx509Cert", }); + new java.lang.String[] { "Byzcoin", "X509Cert", }); internal_static_ocs_PolicyByzCoin_descriptor = - getDescriptor().getMessageTypes().get(8); + getDescriptor().getMessageTypes().get(11); internal_static_ocs_PolicyByzCoin_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_PolicyByzCoin_descriptor, new java.lang.String[] { "Byzcoinid", "Ttl", }); internal_static_ocs_PolicyX509Cert_descriptor = - getDescriptor().getMessageTypes().get(9); + getDescriptor().getMessageTypes().get(12); internal_static_ocs_PolicyX509Cert_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_PolicyX509Cert_descriptor, new java.lang.String[] { "Ca", "Threshold", }); + internal_static_ocs_AuthCreate_descriptor = + getDescriptor().getMessageTypes().get(13); + internal_static_ocs_AuthCreate_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AuthCreate_descriptor, + new java.lang.String[] { "Byzcoin", "X509Cert", }); + internal_static_ocs_AuthCreateByzcoin_descriptor = + getDescriptor().getMessageTypes().get(14); + internal_static_ocs_AuthCreateByzcoin_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AuthCreateByzcoin_descriptor, + new java.lang.String[] { "Byzcoinid", "Ltsinstance", }); + internal_static_ocs_AuthCreateX509Cert_descriptor = + getDescriptor().getMessageTypes().get(15); + internal_static_ocs_AuthCreateX509Cert_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_AuthCreateX509Cert_descriptor, + new java.lang.String[] { "Certificates", }); internal_static_ocs_AuthReencrypt_descriptor = - getDescriptor().getMessageTypes().get(10); + getDescriptor().getMessageTypes().get(16); internal_static_ocs_AuthReencrypt_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_AuthReencrypt_descriptor, - new java.lang.String[] { "Byzcoin", "X509Cert", }); + new java.lang.String[] { "Ephemeral", "Byzcoin", "X509Cert", }); internal_static_ocs_AuthReencryptByzCoin_descriptor = - getDescriptor().getMessageTypes().get(11); + getDescriptor().getMessageTypes().get(17); internal_static_ocs_AuthReencryptByzCoin_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_AuthReencryptByzCoin_descriptor, - new java.lang.String[] { "Write", "Read", }); + new java.lang.String[] { "Write", "Read", "Ephemeral", "Signature", }); internal_static_ocs_AuthReencryptX509Cert_descriptor = - getDescriptor().getMessageTypes().get(12); + getDescriptor().getMessageTypes().get(18); internal_static_ocs_AuthReencryptX509Cert_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_AuthReencryptX509Cert_descriptor, - new java.lang.String[] { "Secret", "Certificates", }); + new java.lang.String[] { "U", "Certificates", }); internal_static_ocs_AuthReshare_descriptor = - getDescriptor().getMessageTypes().get(13); + getDescriptor().getMessageTypes().get(19); internal_static_ocs_AuthReshare_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_AuthReshare_descriptor, new java.lang.String[] { "Byzcoin", "X509Cert", }); internal_static_ocs_AuthReshareByzCoin_descriptor = - getDescriptor().getMessageTypes().get(14); + getDescriptor().getMessageTypes().get(20); internal_static_ocs_AuthReshareByzCoin_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_AuthReshareByzCoin_descriptor, new java.lang.String[] { "Reshare", }); internal_static_ocs_AuthReshareX509Cert_descriptor = - getDescriptor().getMessageTypes().get(15); + getDescriptor().getMessageTypes().get(21); internal_static_ocs_AuthReshareX509Cert_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_ocs_AuthReshareX509Cert_descriptor, new java.lang.String[] { "Certificates", }); + internal_static_ocs_OCSProof_descriptor = + getDescriptor().getMessageTypes().get(22); + internal_static_ocs_OCSProof_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_ocs_OCSProof_descriptor, + new java.lang.String[] { "Ocsid", "Roster", "Policyreencrypt", "Policyreshare", "Signatures", }); ch.epfl.dedis.lib.proto.OnetProto.getDescriptor(); + ch.epfl.dedis.lib.proto.DarcProto.getDescriptor(); } // @@protoc_insertion_point(outer_class_scope) diff --git a/external/js/cothority/package-lock.json b/external/js/cothority/package-lock.json index d00758b590..937fe271d8 100644 --- a/external/js/cothority/package-lock.json +++ b/external/js/cothority/package-lock.json @@ -3083,7 +3083,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -3104,12 +3105,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3124,17 +3127,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3251,7 +3257,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3263,6 +3270,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3277,6 +3285,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3284,12 +3293,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3308,6 +3319,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3388,7 +3400,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3400,6 +3413,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3485,7 +3499,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3521,6 +3536,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3540,6 +3556,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3583,12 +3600,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/external/js/cothority/src/protobuf/models.json b/external/js/cothority/src/protobuf/models.json index a44d4b27a5..59a8ef3812 100644 --- a/external/js/cothority/src/protobuf/models.json +++ b/external/js/cothority/src/protobuf/models.json @@ -1 +1 @@ -{"nested":{"cothority":{},"authprox":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"AuthProxProto"},"nested":{"EnrollRequest":{"fields":{"type":{"rule":"required","type":"string","id":1},"issuer":{"rule":"required","type":"string","id":2},"participants":{"rule":"repeated","type":"bytes","id":3},"longpri":{"rule":"required","type":"PriShare","id":4},"longpubs":{"rule":"repeated","type":"bytes","id":5}}},"EnrollResponse":{"fields":{}},"SignatureRequest":{"fields":{"type":{"rule":"required","type":"string","id":1},"issuer":{"rule":"required","type":"string","id":2},"authinfo":{"rule":"required","type":"bytes","id":3},"randpri":{"rule":"required","type":"PriShare","id":4},"randpubs":{"rule":"repeated","type":"bytes","id":5},"message":{"rule":"required","type":"bytes","id":6}}},"PriShare":{"fields":{}},"PartialSig":{"fields":{"partial":{"rule":"required","type":"PriShare","id":1},"sessionid":{"rule":"required","type":"bytes","id":2},"signature":{"rule":"required","type":"bytes","id":3}}},"SignatureResponse":{"fields":{"partialsignature":{"rule":"required","type":"PartialSig","id":1}}},"EnrollmentsRequest":{"fields":{"types":{"rule":"repeated","type":"string","id":1},"issuers":{"rule":"repeated","type":"string","id":2}}},"EnrollmentsResponse":{"fields":{"enrollments":{"rule":"repeated","type":"EnrollmentInfo","id":1,"options":{"packed":false}}}},"EnrollmentInfo":{"fields":{"type":{"rule":"required","type":"string","id":1},"issuer":{"rule":"required","type":"string","id":2},"public":{"rule":"required","type":"bytes","id":3}}}}},"byzcoin":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"ByzCoinProto"},"nested":{"DataHeader":{"fields":{"trieroot":{"rule":"required","type":"bytes","id":1},"clienttransactionhash":{"rule":"required","type":"bytes","id":2},"statechangeshash":{"rule":"required","type":"bytes","id":3},"timestamp":{"rule":"required","type":"sint64","id":4}}},"DataBody":{"fields":{"txresults":{"rule":"repeated","type":"TxResult","id":1,"options":{"packed":false}}}},"CreateGenesisBlock":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"roster":{"rule":"required","type":"onet.Roster","id":2},"genesisdarc":{"rule":"required","type":"darc.Darc","id":3},"blockinterval":{"rule":"required","type":"sint64","id":4},"maxblocksize":{"type":"sint32","id":5},"darccontractids":{"rule":"repeated","type":"string","id":6}}},"CreateGenesisBlockResponse":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"skipblock":{"type":"skipchain.SkipBlock","id":2}}},"AddTxRequest":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"skipchainid":{"rule":"required","type":"bytes","id":2},"transaction":{"rule":"required","type":"ClientTransaction","id":3},"inclusionwait":{"type":"sint32","id":4}}},"AddTxResponse":{"fields":{"version":{"rule":"required","type":"sint32","id":1}}},"GetProof":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"key":{"rule":"required","type":"bytes","id":2},"id":{"rule":"required","type":"bytes","id":3}}},"GetProofResponse":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"proof":{"rule":"required","type":"Proof","id":2}}},"CheckAuthorization":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"byzcoinid":{"rule":"required","type":"bytes","id":2},"darcid":{"rule":"required","type":"bytes","id":3},"identities":{"rule":"repeated","type":"darc.Identity","id":4,"options":{"packed":false}}}},"CheckAuthorizationResponse":{"fields":{"actions":{"rule":"repeated","type":"string","id":1}}},"ChainConfig":{"fields":{"blockinterval":{"rule":"required","type":"sint64","id":1},"roster":{"rule":"required","type":"onet.Roster","id":2},"maxblocksize":{"rule":"required","type":"sint32","id":3},"darccontractids":{"rule":"repeated","type":"string","id":4}}},"Proof":{"fields":{"inclusionproof":{"rule":"required","type":"trie.Proof","id":1},"latest":{"rule":"required","type":"skipchain.SkipBlock","id":2},"links":{"rule":"repeated","type":"skipchain.ForwardLink","id":3,"options":{"packed":false}}}},"Instruction":{"fields":{"instanceid":{"rule":"required","type":"bytes","id":1},"spawn":{"type":"Spawn","id":2},"invoke":{"type":"Invoke","id":3},"delete":{"type":"Delete","id":4},"signercounter":{"rule":"repeated","type":"uint64","id":5,"options":{"packed":true}},"signeridentities":{"rule":"repeated","type":"darc.Identity","id":6,"options":{"packed":false}},"signatures":{"rule":"repeated","type":"bytes","id":7}}},"Spawn":{"fields":{"contractid":{"rule":"required","type":"string","id":1},"args":{"rule":"repeated","type":"Argument","id":2,"options":{"packed":false}}}},"Invoke":{"fields":{"contractid":{"rule":"required","type":"string","id":1},"command":{"rule":"required","type":"string","id":2},"args":{"rule":"repeated","type":"Argument","id":3,"options":{"packed":false}}}},"Delete":{"fields":{"contractid":{"rule":"required","type":"string","id":1}}},"Argument":{"fields":{"name":{"rule":"required","type":"string","id":1},"value":{"rule":"required","type":"bytes","id":2}}},"ClientTransaction":{"fields":{"instructions":{"rule":"repeated","type":"Instruction","id":1,"options":{"packed":false}}}},"TxResult":{"fields":{"clienttransaction":{"rule":"required","type":"ClientTransaction","id":1},"accepted":{"rule":"required","type":"bool","id":2}}},"StateChange":{"fields":{"stateaction":{"rule":"required","type":"sint32","id":1},"instanceid":{"rule":"required","type":"bytes","id":2},"contractid":{"rule":"required","type":"string","id":3},"value":{"rule":"required","type":"bytes","id":4},"darcid":{"rule":"required","type":"bytes","id":5},"version":{"rule":"required","type":"uint64","id":6}}},"Coin":{"fields":{"name":{"rule":"required","type":"bytes","id":1},"value":{"rule":"required","type":"uint64","id":2}}},"StreamingRequest":{"fields":{"id":{"rule":"required","type":"bytes","id":1}}},"StreamingResponse":{"fields":{"block":{"type":"skipchain.SkipBlock","id":1}}},"DownloadState":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"nonce":{"rule":"required","type":"uint64","id":2},"length":{"rule":"required","type":"sint32","id":3}}},"DownloadStateResponse":{"fields":{"keyvalues":{"rule":"repeated","type":"DBKeyValue","id":1,"options":{"packed":false}},"nonce":{"rule":"required","type":"uint64","id":2}}},"DBKeyValue":{"fields":{"key":{"rule":"required","type":"bytes","id":1},"value":{"rule":"required","type":"bytes","id":2}}},"StateChangeBody":{"fields":{"stateaction":{"rule":"required","type":"sint32","id":1},"contractid":{"rule":"required","type":"string","id":2},"value":{"rule":"required","type":"bytes","id":3},"version":{"rule":"required","type":"uint64","id":4},"darcid":{"rule":"required","type":"bytes","id":5}}},"GetSignerCounters":{"fields":{"signerids":{"rule":"repeated","type":"string","id":1},"skipchainid":{"rule":"required","type":"bytes","id":2}}},"GetSignerCountersResponse":{"fields":{"counters":{"rule":"repeated","type":"uint64","id":1,"options":{"packed":true}}}},"GetInstanceVersion":{"fields":{"skipchainid":{"rule":"required","type":"bytes","id":1},"instanceid":{"rule":"required","type":"bytes","id":2},"version":{"rule":"required","type":"uint64","id":3}}},"GetLastInstanceVersion":{"fields":{"skipchainid":{"rule":"required","type":"bytes","id":1},"instanceid":{"rule":"required","type":"bytes","id":2}}},"GetInstanceVersionResponse":{"fields":{"statechange":{"rule":"required","type":"StateChange","id":1},"blockindex":{"rule":"required","type":"sint32","id":2}}},"GetAllInstanceVersion":{"fields":{"skipchainid":{"rule":"required","type":"bytes","id":1},"instanceid":{"rule":"required","type":"bytes","id":2}}},"GetAllInstanceVersionResponse":{"fields":{"statechanges":{"rule":"repeated","type":"GetInstanceVersionResponse","id":1,"options":{"packed":false}}}},"CheckStateChangeValidity":{"fields":{"skipchainid":{"rule":"required","type":"bytes","id":1},"instanceid":{"rule":"required","type":"bytes","id":2},"version":{"rule":"required","type":"uint64","id":3}}},"CheckStateChangeValidityResponse":{"fields":{"statechanges":{"rule":"repeated","type":"StateChange","id":1,"options":{"packed":false}},"blockid":{"rule":"required","type":"bytes","id":2}}},"DebugRequest":{"fields":{"byzcoinid":{"type":"bytes","id":1}}},"DebugResponse":{"fields":{"byzcoins":{"rule":"repeated","type":"DebugResponseByzcoin","id":1,"options":{"packed":false}},"dump":{"rule":"repeated","type":"DebugResponseState","id":2,"options":{"packed":false}}}},"DebugResponseByzcoin":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"genesis":{"type":"skipchain.SkipBlock","id":2},"latest":{"type":"skipchain.SkipBlock","id":3}}},"DebugResponseState":{"fields":{"key":{"rule":"required","type":"bytes","id":1},"state":{"rule":"required","type":"StateChangeBody","id":2}}},"DebugRemoveRequest":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"signature":{"rule":"required","type":"bytes","id":2}}}}},"skipchain":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"SkipchainProto"},"nested":{"StoreSkipBlock":{"fields":{"targetSkipChainID":{"rule":"required","type":"bytes","id":1},"newBlock":{"rule":"required","type":"SkipBlock","id":2},"signature":{"type":"bytes","id":3}}},"StoreSkipBlockReply":{"fields":{"previous":{"type":"SkipBlock","id":1},"latest":{"rule":"required","type":"SkipBlock","id":2}}},"GetAllSkipChainIDs":{"fields":{}},"GetAllSkipChainIDsReply":{"fields":{"skipChainIDs":{"rule":"repeated","type":"bytes","id":1}}},"GetSingleBlock":{"fields":{"id":{"rule":"required","type":"bytes","id":1}}},"GetSingleBlockByIndex":{"fields":{"genesis":{"rule":"required","type":"bytes","id":1},"index":{"rule":"required","type":"sint32","id":2}}},"GetSingleBlockByIndexReply":{"fields":{"skipblock":{"rule":"required","type":"SkipBlock","id":1},"links":{"rule":"repeated","type":"ForwardLink","id":2,"options":{"packed":false}}}},"GetUpdateChain":{"fields":{"latestID":{"rule":"required","type":"bytes","id":1}}},"GetUpdateChainReply":{"fields":{"update":{"rule":"repeated","type":"SkipBlock","id":1,"options":{"packed":false}}}},"SkipBlock":{"fields":{"index":{"rule":"required","type":"sint32","id":1},"height":{"rule":"required","type":"sint32","id":2},"maxHeight":{"rule":"required","type":"sint32","id":3},"baseHeight":{"rule":"required","type":"sint32","id":4},"backlinks":{"rule":"repeated","type":"bytes","id":5},"verifiers":{"rule":"repeated","type":"bytes","id":6},"genesis":{"rule":"required","type":"bytes","id":7},"data":{"rule":"required","type":"bytes","id":8},"roster":{"rule":"required","type":"onet.Roster","id":9},"hash":{"rule":"required","type":"bytes","id":10},"forward":{"rule":"repeated","type":"ForwardLink","id":11,"options":{"packed":false}},"payload":{"type":"bytes","id":12}}},"ForwardLink":{"fields":{"from":{"rule":"required","type":"bytes","id":1},"to":{"rule":"required","type":"bytes","id":2},"newRoster":{"type":"onet.Roster","id":3},"signature":{"rule":"required","type":"ByzcoinSig","id":4}}},"ByzcoinSig":{"fields":{"msg":{"rule":"required","type":"bytes","id":1},"sig":{"rule":"required","type":"bytes","id":2}}},"SchnorrSig":{"fields":{"challenge":{"rule":"required","type":"bytes","id":1},"response":{"rule":"required","type":"bytes","id":2}}},"Exception":{"fields":{"index":{"rule":"required","type":"sint32","id":1},"commitment":{"rule":"required","type":"bytes","id":2}}}}},"onet":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"OnetProto"},"nested":{"Roster":{"fields":{"id":{"type":"bytes","id":1},"list":{"rule":"repeated","type":"network.ServerIdentity","id":2,"options":{"packed":false}},"aggregate":{"rule":"required","type":"bytes","id":3}}},"Status":{"fields":{"field":{"keyType":"string","type":"string","id":1}}}}},"network":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"NetworkProto"},"nested":{"ServerIdentity":{"fields":{"public":{"rule":"required","type":"bytes","id":1},"serviceIdentities":{"rule":"repeated","type":"ServiceIdentity","id":2,"options":{"packed":false}},"id":{"rule":"required","type":"bytes","id":3},"address":{"rule":"required","type":"string","id":4},"description":{"rule":"required","type":"string","id":5},"url":{"type":"string","id":6}}},"ServiceIdentity":{"fields":{"name":{"rule":"required","type":"string","id":1},"suite":{"rule":"required","type":"string","id":2},"public":{"rule":"required","type":"bytes","id":3}}}}},"darc":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"DarcProto"},"nested":{"Darc":{"fields":{"version":{"rule":"required","type":"uint64","id":1},"description":{"rule":"required","type":"bytes","id":2},"baseid":{"type":"bytes","id":3},"previd":{"rule":"required","type":"bytes","id":4},"rules":{"rule":"required","type":"Rules","id":5},"signatures":{"rule":"repeated","type":"Signature","id":6,"options":{"packed":false}},"verificationdarcs":{"rule":"repeated","type":"Darc","id":7,"options":{"packed":false}}}},"Identity":{"fields":{"darc":{"type":"IdentityDarc","id":1},"ed25519":{"type":"IdentityEd25519","id":2},"x509ec":{"type":"IdentityX509EC","id":3},"proxy":{"type":"IdentityProxy","id":4}}},"IdentityEd25519":{"fields":{"point":{"rule":"required","type":"bytes","id":1}}},"IdentityX509EC":{"fields":{"public":{"rule":"required","type":"bytes","id":1}}},"IdentityProxy":{"fields":{"data":{"rule":"required","type":"string","id":1},"public":{"rule":"required","type":"bytes","id":2}}},"IdentityDarc":{"fields":{"id":{"rule":"required","type":"bytes","id":1}}},"Signature":{"fields":{"signature":{"rule":"required","type":"bytes","id":1},"signer":{"rule":"required","type":"Identity","id":2}}},"Signer":{"fields":{"ed25519":{"type":"SignerEd25519","id":1},"x509ec":{"type":"SignerX509EC","id":2},"proxy":{"type":"SignerProxy","id":3}}},"SignerEd25519":{"fields":{"point":{"rule":"required","type":"bytes","id":1},"secret":{"rule":"required","type":"bytes","id":2}}},"SignerX509EC":{"fields":{"point":{"rule":"required","type":"bytes","id":1}}},"SignerProxy":{"fields":{"data":{"rule":"required","type":"string","id":1},"public":{"rule":"required","type":"bytes","id":2}}},"Request":{"fields":{"baseid":{"rule":"required","type":"bytes","id":1},"action":{"rule":"required","type":"string","id":2},"msg":{"rule":"required","type":"bytes","id":3},"identities":{"rule":"repeated","type":"Identity","id":4,"options":{"packed":false}},"signatures":{"rule":"repeated","type":"bytes","id":5}}},"Rules":{"fields":{"list":{"rule":"repeated","type":"Rule","id":1,"options":{"packed":false}}}},"Rule":{"fields":{"action":{"rule":"required","type":"string","id":1},"expr":{"rule":"required","type":"bytes","id":2}}}}},"trie":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"TrieProto"},"nested":{"InteriorNode":{"fields":{"left":{"rule":"required","type":"bytes","id":1},"right":{"rule":"required","type":"bytes","id":2}}},"EmptyNode":{"fields":{"prefix":{"rule":"repeated","type":"bool","id":1,"options":{"packed":true}}}},"LeafNode":{"fields":{"prefix":{"rule":"repeated","type":"bool","id":1,"options":{"packed":true}},"key":{"rule":"required","type":"bytes","id":2},"value":{"rule":"required","type":"bytes","id":3}}},"Proof":{"fields":{"interiors":{"rule":"repeated","type":"InteriorNode","id":1,"options":{"packed":false}},"leaf":{"rule":"required","type":"LeafNode","id":2},"empty":{"rule":"required","type":"EmptyNode","id":3},"nonce":{"rule":"required","type":"bytes","id":4}}}}},"calypso":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"Calypso"},"nested":{"Write":{"fields":{"data":{"rule":"required","type":"bytes","id":1},"u":{"rule":"required","type":"bytes","id":2},"ubar":{"rule":"required","type":"bytes","id":3},"e":{"rule":"required","type":"bytes","id":4},"f":{"rule":"required","type":"bytes","id":5},"c":{"rule":"required","type":"bytes","id":6},"extradata":{"type":"bytes","id":7},"ltsid":{"rule":"required","type":"bytes","id":8}}},"Read":{"fields":{"write":{"rule":"required","type":"bytes","id":1},"xc":{"rule":"required","type":"bytes","id":2}}},"Authorise":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1}}},"AuthoriseReply":{"fields":{}},"CreateLTS":{"fields":{"proof":{"rule":"required","type":"byzcoin.Proof","id":1}}},"CreateLTSReply":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"instanceid":{"rule":"required","type":"bytes","id":2},"x":{"rule":"required","type":"bytes","id":3}}},"ReshareLTS":{"fields":{"proof":{"rule":"required","type":"byzcoin.Proof","id":1}}},"ReshareLTSReply":{"fields":{}},"DecryptKey":{"fields":{"read":{"rule":"required","type":"byzcoin.Proof","id":1},"write":{"rule":"required","type":"byzcoin.Proof","id":2}}},"DecryptKeyReply":{"fields":{"c":{"rule":"required","type":"bytes","id":1},"xhatenc":{"rule":"required","type":"bytes","id":2},"x":{"rule":"required","type":"bytes","id":3}}},"GetLTSReply":{"fields":{"ltsid":{"rule":"required","type":"bytes","id":1}}},"LtsInstanceInfo":{"fields":{"roster":{"rule":"required","type":"onet.Roster","id":1}}}}},"eventlog":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"EventLogProto"},"nested":{"SearchRequest":{"fields":{"instance":{"rule":"required","type":"bytes","id":1},"id":{"rule":"required","type":"bytes","id":2},"topic":{"rule":"required","type":"string","id":3},"from":{"rule":"required","type":"sint64","id":4},"to":{"rule":"required","type":"sint64","id":5}}},"SearchResponse":{"fields":{"events":{"rule":"repeated","type":"Event","id":1,"options":{"packed":false}},"truncated":{"rule":"required","type":"bool","id":2}}},"Event":{"fields":{"when":{"rule":"required","type":"sint64","id":1},"topic":{"rule":"required","type":"string","id":2},"content":{"rule":"required","type":"string","id":3}}}}},"personhood":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"Personhood"},"nested":{"PartyList":{"fields":{"newparty":{"type":"Party","id":1},"wipeparties":{"type":"bool","id":2}}},"PartyListResponse":{"fields":{"parties":{"rule":"repeated","type":"Party","id":1,"options":{"packed":false}}}},"Party":{"fields":{"roster":{"rule":"required","type":"onet.Roster","id":1},"byzcoinid":{"rule":"required","type":"bytes","id":2},"instanceid":{"rule":"required","type":"bytes","id":3}}},"RoPaSciList":{"fields":{"newropasci":{"type":"RoPaSci","id":1},"wipe":{"type":"bool","id":2}}},"RoPaSciListResponse":{"fields":{"ropascis":{"rule":"repeated","type":"RoPaSci","id":1,"options":{"packed":false}}}},"RoPaSci":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"ropasciid":{"rule":"required","type":"bytes","id":2}}},"StringReply":{"fields":{"reply":{"rule":"required","type":"string","id":1}}},"RoPaSciStruct":{"fields":{"description":{"rule":"required","type":"string","id":1},"stake":{"rule":"required","type":"byzcoin.Coin","id":2},"firstplayerhash":{"rule":"required","type":"bytes","id":3},"firstplayer":{"type":"sint32","id":4},"secondplayer":{"type":"sint32","id":5},"secondplayeraccount":{"type":"bytes","id":6}}},"CredentialStruct":{"fields":{"credentials":{"rule":"repeated","type":"Credential","id":1,"options":{"packed":false}}}},"Credential":{"fields":{"name":{"rule":"required","type":"string","id":1},"attributes":{"rule":"repeated","type":"Attribute","id":2,"options":{"packed":false}}}},"Attribute":{"fields":{"name":{"rule":"required","type":"string","id":1},"value":{"rule":"required","type":"bytes","id":2}}},"SpawnerStruct":{"fields":{"costdarc":{"rule":"required","type":"byzcoin.Coin","id":1},"costcoin":{"rule":"required","type":"byzcoin.Coin","id":2},"costcredential":{"rule":"required","type":"byzcoin.Coin","id":3},"costparty":{"rule":"required","type":"byzcoin.Coin","id":4},"beneficiary":{"rule":"required","type":"bytes","id":5},"costropasci":{"type":"byzcoin.Coin","id":6}}},"PopPartyStruct":{"fields":{"state":{"rule":"required","type":"sint32","id":1},"organizers":{"rule":"required","type":"sint32","id":2},"finalizations":{"rule":"repeated","type":"string","id":3},"description":{"rule":"required","type":"PopDesc","id":4},"attendees":{"rule":"required","type":"Attendees","id":5},"miners":{"rule":"repeated","type":"LRSTag","id":6,"options":{"packed":false}},"miningreward":{"rule":"required","type":"uint64","id":7},"previous":{"type":"bytes","id":8},"next":{"type":"bytes","id":9}}},"PopDesc":{"fields":{"name":{"rule":"required","type":"string","id":1},"purpose":{"rule":"required","type":"string","id":2},"datetime":{"rule":"required","type":"uint64","id":3},"location":{"rule":"required","type":"string","id":4}}},"FinalStatement":{"fields":{"desc":{"type":"PopDesc","id":1},"attendees":{"rule":"required","type":"Attendees","id":2}}},"Attendees":{"fields":{"keys":{"rule":"repeated","type":"bytes","id":1}}},"LRSTag":{"fields":{"tag":{"rule":"required","type":"bytes","id":1}}},"Poll":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"newpoll":{"type":"PollStruct","id":2},"list":{"type":"PollList","id":3},"answer":{"type":"PollAnswer","id":4}}},"PollList":{"fields":{"partyids":{"rule":"repeated","type":"bytes","id":1}}},"PollAnswer":{"fields":{"pollid":{"rule":"required","type":"bytes","id":1},"choice":{"rule":"required","type":"sint32","id":2},"lrs":{"rule":"required","type":"bytes","id":3}}},"PollStruct":{"fields":{"personhood":{"rule":"required","type":"bytes","id":1},"pollid":{"type":"bytes","id":2},"title":{"rule":"required","type":"string","id":3},"description":{"rule":"required","type":"string","id":4},"choices":{"rule":"repeated","type":"string","id":5},"chosen":{"rule":"repeated","type":"PollChoice","id":6,"options":{"packed":false}}}},"PollChoice":{"fields":{"choice":{"rule":"required","type":"sint32","id":1},"lrstag":{"rule":"required","type":"bytes","id":2}}},"PollResponse":{"fields":{"polls":{"rule":"repeated","type":"PollStruct","id":1,"options":{"packed":false}}}},"Capabilities":{"fields":{}},"CapabilitiesResponse":{"fields":{"capabilities":{"rule":"repeated","type":"Capability","id":1,"options":{"packed":false}}}},"Capability":{"fields":{"endpoint":{"rule":"required","type":"string","id":1},"version":{"rule":"required","type":"bytes","id":2}}},"UserLocation":{"fields":{"publickey":{"rule":"required","type":"bytes","id":1},"credentialiid":{"type":"bytes","id":2},"credential":{"type":"CredentialStruct","id":3},"location":{"type":"string","id":4},"time":{"rule":"required","type":"sint64","id":5}}},"Meetup":{"fields":{"userlocation":{"type":"UserLocation","id":1},"wipe":{"type":"bool","id":2}}},"MeetupResponse":{"fields":{"users":{"rule":"repeated","type":"UserLocation","id":1,"options":{"packed":false}}}}}},"status":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"StatusProto"},"nested":{"Request":{"fields":{}},"Response":{"fields":{"status":{"keyType":"string","type":"onet.Status","id":1},"serveridentity":{"type":"network.ServerIdentity","id":2}}}}}}} \ No newline at end of file +{"nested":{"cothority":{},"authprox":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"AuthProxProto"},"nested":{"EnrollRequest":{"fields":{"type":{"rule":"required","type":"string","id":1},"issuer":{"rule":"required","type":"string","id":2},"participants":{"rule":"repeated","type":"bytes","id":3},"longpri":{"rule":"required","type":"PriShare","id":4},"longpubs":{"rule":"repeated","type":"bytes","id":5}}},"EnrollResponse":{"fields":{}},"SignatureRequest":{"fields":{"type":{"rule":"required","type":"string","id":1},"issuer":{"rule":"required","type":"string","id":2},"authinfo":{"rule":"required","type":"bytes","id":3},"randpri":{"rule":"required","type":"PriShare","id":4},"randpubs":{"rule":"repeated","type":"bytes","id":5},"message":{"rule":"required","type":"bytes","id":6}}},"PriShare":{"fields":{}},"PartialSig":{"fields":{"partial":{"rule":"required","type":"PriShare","id":1},"sessionid":{"rule":"required","type":"bytes","id":2},"signature":{"rule":"required","type":"bytes","id":3}}},"SignatureResponse":{"fields":{"partialsignature":{"rule":"required","type":"PartialSig","id":1}}},"EnrollmentsRequest":{"fields":{"types":{"rule":"repeated","type":"string","id":1},"issuers":{"rule":"repeated","type":"string","id":2}}},"EnrollmentsResponse":{"fields":{"enrollments":{"rule":"repeated","type":"EnrollmentInfo","id":1,"options":{"packed":false}}}},"EnrollmentInfo":{"fields":{"type":{"rule":"required","type":"string","id":1},"issuer":{"rule":"required","type":"string","id":2},"public":{"rule":"required","type":"bytes","id":3}}}}},"byzcoin":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"ByzCoinProto"},"nested":{"DataHeader":{"fields":{"trieroot":{"rule":"required","type":"bytes","id":1},"clienttransactionhash":{"rule":"required","type":"bytes","id":2},"statechangeshash":{"rule":"required","type":"bytes","id":3},"timestamp":{"rule":"required","type":"sint64","id":4}}},"DataBody":{"fields":{"txresults":{"rule":"repeated","type":"TxResult","id":1,"options":{"packed":false}}}},"CreateGenesisBlock":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"roster":{"rule":"required","type":"onet.Roster","id":2},"genesisdarc":{"rule":"required","type":"darc.Darc","id":3},"blockinterval":{"rule":"required","type":"sint64","id":4},"maxblocksize":{"type":"sint32","id":5},"darccontractids":{"rule":"repeated","type":"string","id":6}}},"CreateGenesisBlockResponse":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"skipblock":{"type":"skipchain.SkipBlock","id":2}}},"AddTxRequest":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"skipchainid":{"rule":"required","type":"bytes","id":2},"transaction":{"rule":"required","type":"ClientTransaction","id":3},"inclusionwait":{"type":"sint32","id":4}}},"AddTxResponse":{"fields":{"version":{"rule":"required","type":"sint32","id":1}}},"GetProof":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"key":{"rule":"required","type":"bytes","id":2},"id":{"rule":"required","type":"bytes","id":3}}},"GetProofResponse":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"proof":{"rule":"required","type":"Proof","id":2}}},"CheckAuthorization":{"fields":{"version":{"rule":"required","type":"sint32","id":1},"byzcoinid":{"rule":"required","type":"bytes","id":2},"darcid":{"rule":"required","type":"bytes","id":3},"identities":{"rule":"repeated","type":"darc.Identity","id":4,"options":{"packed":false}}}},"CheckAuthorizationResponse":{"fields":{"actions":{"rule":"repeated","type":"string","id":1}}},"ChainConfig":{"fields":{"blockinterval":{"rule":"required","type":"sint64","id":1},"roster":{"rule":"required","type":"onet.Roster","id":2},"maxblocksize":{"rule":"required","type":"sint32","id":3},"darccontractids":{"rule":"repeated","type":"string","id":4}}},"Proof":{"fields":{"inclusionproof":{"rule":"required","type":"trie.Proof","id":1},"latest":{"rule":"required","type":"skipchain.SkipBlock","id":2},"links":{"rule":"repeated","type":"skipchain.ForwardLink","id":3,"options":{"packed":false}}}},"Instruction":{"fields":{"instanceid":{"rule":"required","type":"bytes","id":1},"spawn":{"type":"Spawn","id":2},"invoke":{"type":"Invoke","id":3},"delete":{"type":"Delete","id":4},"signercounter":{"rule":"repeated","type":"uint64","id":5,"options":{"packed":true}},"signeridentities":{"rule":"repeated","type":"darc.Identity","id":6,"options":{"packed":false}},"signatures":{"rule":"repeated","type":"bytes","id":7}}},"Spawn":{"fields":{"contractid":{"rule":"required","type":"string","id":1},"args":{"rule":"repeated","type":"Argument","id":2,"options":{"packed":false}}}},"Invoke":{"fields":{"contractid":{"rule":"required","type":"string","id":1},"command":{"rule":"required","type":"string","id":2},"args":{"rule":"repeated","type":"Argument","id":3,"options":{"packed":false}}}},"Delete":{"fields":{"contractid":{"rule":"required","type":"string","id":1}}},"Argument":{"fields":{"name":{"rule":"required","type":"string","id":1},"value":{"rule":"required","type":"bytes","id":2}}},"ClientTransaction":{"fields":{"instructions":{"rule":"repeated","type":"Instruction","id":1,"options":{"packed":false}}}},"TxResult":{"fields":{"clienttransaction":{"rule":"required","type":"ClientTransaction","id":1},"accepted":{"rule":"required","type":"bool","id":2}}},"StateChange":{"fields":{"stateaction":{"rule":"required","type":"sint32","id":1},"instanceid":{"rule":"required","type":"bytes","id":2},"contractid":{"rule":"required","type":"string","id":3},"value":{"rule":"required","type":"bytes","id":4},"darcid":{"rule":"required","type":"bytes","id":5},"version":{"rule":"required","type":"uint64","id":6}}},"Coin":{"fields":{"name":{"rule":"required","type":"bytes","id":1},"value":{"rule":"required","type":"uint64","id":2}}},"StreamingRequest":{"fields":{"id":{"rule":"required","type":"bytes","id":1}}},"StreamingResponse":{"fields":{"block":{"type":"skipchain.SkipBlock","id":1}}},"DownloadState":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"nonce":{"rule":"required","type":"uint64","id":2},"length":{"rule":"required","type":"sint32","id":3}}},"DownloadStateResponse":{"fields":{"keyvalues":{"rule":"repeated","type":"DBKeyValue","id":1,"options":{"packed":false}},"nonce":{"rule":"required","type":"uint64","id":2}}},"DBKeyValue":{"fields":{"key":{"rule":"required","type":"bytes","id":1},"value":{"rule":"required","type":"bytes","id":2}}},"StateChangeBody":{"fields":{"stateaction":{"rule":"required","type":"sint32","id":1},"contractid":{"rule":"required","type":"string","id":2},"value":{"rule":"required","type":"bytes","id":3},"version":{"rule":"required","type":"uint64","id":4},"darcid":{"rule":"required","type":"bytes","id":5}}},"GetSignerCounters":{"fields":{"signerids":{"rule":"repeated","type":"string","id":1},"skipchainid":{"rule":"required","type":"bytes","id":2}}},"GetSignerCountersResponse":{"fields":{"counters":{"rule":"repeated","type":"uint64","id":1,"options":{"packed":true}}}},"GetInstanceVersion":{"fields":{"skipchainid":{"rule":"required","type":"bytes","id":1},"instanceid":{"rule":"required","type":"bytes","id":2},"version":{"rule":"required","type":"uint64","id":3}}},"GetLastInstanceVersion":{"fields":{"skipchainid":{"rule":"required","type":"bytes","id":1},"instanceid":{"rule":"required","type":"bytes","id":2}}},"GetInstanceVersionResponse":{"fields":{"statechange":{"rule":"required","type":"StateChange","id":1},"blockindex":{"rule":"required","type":"sint32","id":2}}},"GetAllInstanceVersion":{"fields":{"skipchainid":{"rule":"required","type":"bytes","id":1},"instanceid":{"rule":"required","type":"bytes","id":2}}},"GetAllInstanceVersionResponse":{"fields":{"statechanges":{"rule":"repeated","type":"GetInstanceVersionResponse","id":1,"options":{"packed":false}}}},"CheckStateChangeValidity":{"fields":{"skipchainid":{"rule":"required","type":"bytes","id":1},"instanceid":{"rule":"required","type":"bytes","id":2},"version":{"rule":"required","type":"uint64","id":3}}},"CheckStateChangeValidityResponse":{"fields":{"statechanges":{"rule":"repeated","type":"StateChange","id":1,"options":{"packed":false}},"blockid":{"rule":"required","type":"bytes","id":2}}},"DebugRequest":{"fields":{"byzcoinid":{"type":"bytes","id":1}}},"DebugResponse":{"fields":{"byzcoins":{"rule":"repeated","type":"DebugResponseByzcoin","id":1,"options":{"packed":false}},"dump":{"rule":"repeated","type":"DebugResponseState","id":2,"options":{"packed":false}}}},"DebugResponseByzcoin":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"genesis":{"type":"skipchain.SkipBlock","id":2},"latest":{"type":"skipchain.SkipBlock","id":3}}},"DebugResponseState":{"fields":{"key":{"rule":"required","type":"bytes","id":1},"state":{"rule":"required","type":"StateChangeBody","id":2}}},"DebugRemoveRequest":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"signature":{"rule":"required","type":"bytes","id":2}}}}},"skipchain":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"SkipchainProto"},"nested":{"StoreSkipBlock":{"fields":{"targetSkipChainID":{"rule":"required","type":"bytes","id":1},"newBlock":{"rule":"required","type":"SkipBlock","id":2},"signature":{"type":"bytes","id":3}}},"StoreSkipBlockReply":{"fields":{"previous":{"type":"SkipBlock","id":1},"latest":{"rule":"required","type":"SkipBlock","id":2}}},"GetAllSkipChainIDs":{"fields":{}},"GetAllSkipChainIDsReply":{"fields":{"skipChainIDs":{"rule":"repeated","type":"bytes","id":1}}},"GetSingleBlock":{"fields":{"id":{"rule":"required","type":"bytes","id":1}}},"GetSingleBlockByIndex":{"fields":{"genesis":{"rule":"required","type":"bytes","id":1},"index":{"rule":"required","type":"sint32","id":2}}},"GetSingleBlockByIndexReply":{"fields":{"skipblock":{"rule":"required","type":"SkipBlock","id":1},"links":{"rule":"repeated","type":"ForwardLink","id":2,"options":{"packed":false}}}},"GetUpdateChain":{"fields":{"latestID":{"rule":"required","type":"bytes","id":1}}},"GetUpdateChainReply":{"fields":{"update":{"rule":"repeated","type":"SkipBlock","id":1,"options":{"packed":false}}}},"SkipBlock":{"fields":{"index":{"rule":"required","type":"sint32","id":1},"height":{"rule":"required","type":"sint32","id":2},"maxHeight":{"rule":"required","type":"sint32","id":3},"baseHeight":{"rule":"required","type":"sint32","id":4},"backlinks":{"rule":"repeated","type":"bytes","id":5},"verifiers":{"rule":"repeated","type":"bytes","id":6},"genesis":{"rule":"required","type":"bytes","id":7},"data":{"rule":"required","type":"bytes","id":8},"roster":{"rule":"required","type":"onet.Roster","id":9},"hash":{"rule":"required","type":"bytes","id":10},"forward":{"rule":"repeated","type":"ForwardLink","id":11,"options":{"packed":false}},"payload":{"type":"bytes","id":12}}},"ForwardLink":{"fields":{"from":{"rule":"required","type":"bytes","id":1},"to":{"rule":"required","type":"bytes","id":2},"newRoster":{"type":"onet.Roster","id":3},"signature":{"rule":"required","type":"ByzcoinSig","id":4}}},"ByzcoinSig":{"fields":{"msg":{"rule":"required","type":"bytes","id":1},"sig":{"rule":"required","type":"bytes","id":2}}},"SchnorrSig":{"fields":{"challenge":{"rule":"required","type":"bytes","id":1},"response":{"rule":"required","type":"bytes","id":2}}},"Exception":{"fields":{"index":{"rule":"required","type":"sint32","id":1},"commitment":{"rule":"required","type":"bytes","id":2}}}}},"onet":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"OnetProto"},"nested":{"Roster":{"fields":{"id":{"type":"bytes","id":1},"list":{"rule":"repeated","type":"network.ServerIdentity","id":2,"options":{"packed":false}},"aggregate":{"rule":"required","type":"bytes","id":3}}},"Status":{"fields":{"field":{"keyType":"string","type":"string","id":1}}}}},"network":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"NetworkProto"},"nested":{"ServerIdentity":{"fields":{"public":{"rule":"required","type":"bytes","id":1},"serviceIdentities":{"rule":"repeated","type":"ServiceIdentity","id":2,"options":{"packed":false}},"id":{"rule":"required","type":"bytes","id":3},"address":{"rule":"required","type":"string","id":4},"description":{"rule":"required","type":"string","id":5},"url":{"type":"string","id":6}}},"ServiceIdentity":{"fields":{"name":{"rule":"required","type":"string","id":1},"suite":{"rule":"required","type":"string","id":2},"public":{"rule":"required","type":"bytes","id":3}}}}},"darc":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"DarcProto"},"nested":{"Darc":{"fields":{"version":{"rule":"required","type":"uint64","id":1},"description":{"rule":"required","type":"bytes","id":2},"baseid":{"type":"bytes","id":3},"previd":{"rule":"required","type":"bytes","id":4},"rules":{"rule":"required","type":"Rules","id":5},"signatures":{"rule":"repeated","type":"Signature","id":6,"options":{"packed":false}},"verificationdarcs":{"rule":"repeated","type":"Darc","id":7,"options":{"packed":false}}}},"Identity":{"fields":{"darc":{"type":"IdentityDarc","id":1},"ed25519":{"type":"IdentityEd25519","id":2},"x509ec":{"type":"IdentityX509EC","id":3},"proxy":{"type":"IdentityProxy","id":4}}},"IdentityEd25519":{"fields":{"point":{"rule":"required","type":"bytes","id":1}}},"IdentityX509EC":{"fields":{"public":{"rule":"required","type":"bytes","id":1}}},"IdentityProxy":{"fields":{"data":{"rule":"required","type":"string","id":1},"public":{"rule":"required","type":"bytes","id":2}}},"IdentityDarc":{"fields":{"id":{"rule":"required","type":"bytes","id":1}}},"Signature":{"fields":{"signature":{"rule":"required","type":"bytes","id":1},"signer":{"rule":"required","type":"Identity","id":2}}},"Signer":{"fields":{"ed25519":{"type":"SignerEd25519","id":1},"x509ec":{"type":"SignerX509EC","id":2},"proxy":{"type":"SignerProxy","id":3}}},"SignerEd25519":{"fields":{"point":{"rule":"required","type":"bytes","id":1},"secret":{"rule":"required","type":"bytes","id":2}}},"SignerX509EC":{"fields":{"point":{"rule":"required","type":"bytes","id":1}}},"SignerProxy":{"fields":{"data":{"rule":"required","type":"string","id":1},"public":{"rule":"required","type":"bytes","id":2}}},"Request":{"fields":{"baseid":{"rule":"required","type":"bytes","id":1},"action":{"rule":"required","type":"string","id":2},"msg":{"rule":"required","type":"bytes","id":3},"identities":{"rule":"repeated","type":"Identity","id":4,"options":{"packed":false}},"signatures":{"rule":"repeated","type":"bytes","id":5}}},"Rules":{"fields":{"list":{"rule":"repeated","type":"Rule","id":1,"options":{"packed":false}}}},"Rule":{"fields":{"action":{"rule":"required","type":"string","id":1},"expr":{"rule":"required","type":"bytes","id":2}}}}},"trie":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"TrieProto"},"nested":{"InteriorNode":{"fields":{"left":{"rule":"required","type":"bytes","id":1},"right":{"rule":"required","type":"bytes","id":2}}},"EmptyNode":{"fields":{"prefix":{"rule":"repeated","type":"bool","id":1,"options":{"packed":true}}}},"LeafNode":{"fields":{"prefix":{"rule":"repeated","type":"bool","id":1,"options":{"packed":true}},"key":{"rule":"required","type":"bytes","id":2},"value":{"rule":"required","type":"bytes","id":3}}},"Proof":{"fields":{"interiors":{"rule":"repeated","type":"InteriorNode","id":1,"options":{"packed":false}},"leaf":{"rule":"required","type":"LeafNode","id":2},"empty":{"rule":"required","type":"EmptyNode","id":3},"nonce":{"rule":"required","type":"bytes","id":4}}}}},"calypso":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"Calypso"},"nested":{"Write":{"fields":{"data":{"rule":"required","type":"bytes","id":1},"u":{"rule":"required","type":"bytes","id":2},"ubar":{"rule":"required","type":"bytes","id":3},"e":{"rule":"required","type":"bytes","id":4},"f":{"rule":"required","type":"bytes","id":5},"c":{"rule":"required","type":"bytes","id":6},"extradata":{"type":"bytes","id":7},"ltsid":{"rule":"required","type":"bytes","id":8}}},"Read":{"fields":{"write":{"rule":"required","type":"bytes","id":1},"xc":{"rule":"required","type":"bytes","id":2}}},"Authorise":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1}}},"AuthoriseReply":{"fields":{}},"CreateLTS":{"fields":{"proof":{"rule":"required","type":"byzcoin.Proof","id":1}}},"CreateLTSReply":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"instanceid":{"rule":"required","type":"bytes","id":2},"x":{"rule":"required","type":"bytes","id":3}}},"ReshareLTS":{"fields":{"proof":{"rule":"required","type":"byzcoin.Proof","id":1}}},"ReshareLTSReply":{"fields":{}},"DecryptKey":{"fields":{"read":{"rule":"required","type":"byzcoin.Proof","id":1},"write":{"rule":"required","type":"byzcoin.Proof","id":2}}},"DecryptKeyReply":{"fields":{"c":{"rule":"required","type":"bytes","id":1},"xhatenc":{"rule":"required","type":"bytes","id":2},"x":{"rule":"required","type":"bytes","id":3}}},"GetLTSReply":{"fields":{"ltsid":{"rule":"required","type":"bytes","id":1}}},"LtsInstanceInfo":{"fields":{"roster":{"rule":"required","type":"onet.Roster","id":1}}}}},"eventlog":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"EventLogProto"},"nested":{"SearchRequest":{"fields":{"instance":{"rule":"required","type":"bytes","id":1},"id":{"rule":"required","type":"bytes","id":2},"topic":{"rule":"required","type":"string","id":3},"from":{"rule":"required","type":"sint64","id":4},"to":{"rule":"required","type":"sint64","id":5}}},"SearchResponse":{"fields":{"events":{"rule":"repeated","type":"Event","id":1,"options":{"packed":false}},"truncated":{"rule":"required","type":"bool","id":2}}},"Event":{"fields":{"when":{"rule":"required","type":"sint64","id":1},"topic":{"rule":"required","type":"string","id":2},"content":{"rule":"required","type":"string","id":3}}}}},"ocs":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"OCS"},"nested":{"AddPolicyCreateOCS":{"fields":{"create":{"rule":"required","type":"Policy","id":1}}},"AddPolicyCreateOCSReply":{"fields":{}},"CreateOCS":{"fields":{"roster":{"rule":"required","type":"onet.Roster","id":1},"policyreencrypt":{"rule":"required","type":"Policy","id":2},"policyreshare":{"rule":"required","type":"Policy","id":3}}},"CreateOCSReply":{"fields":{"ocsid":{"rule":"required","type":"bytes","id":1}}},"GetProof":{"fields":{"ocsid":{"rule":"required","type":"bytes","id":1}}},"GetProofReply":{"fields":{"proof":{"rule":"required","type":"OCSProof","id":1}}},"Reencrypt":{"fields":{"ocsid":{"rule":"required","type":"bytes","id":1},"auth":{"rule":"required","type":"AuthReencrypt","id":2}}},"ReencryptReply":{"fields":{"x":{"rule":"required","type":"bytes","id":1},"xhatenc":{"rule":"required","type":"bytes","id":2},"c":{"rule":"required","type":"bytes","id":3}}},"Reshare":{"fields":{"ocsid":{"rule":"required","type":"bytes","id":1},"newroster":{"rule":"required","type":"onet.Roster","id":2},"auth":{"rule":"required","type":"AuthReshare","id":3}}},"ReshareReply":{"fields":{"sig":{"rule":"required","type":"bytes","id":1}}},"Policy":{"fields":{"byzcoin":{"type":"PolicyByzCoin","id":1},"x509cert":{"type":"PolicyX509Cert","id":2}}},"PolicyByzCoin":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"ttl":{"rule":"required","type":"uint64","id":2}}},"PolicyX509Cert":{"fields":{"ca":{"rule":"repeated","type":"bytes","id":1},"threshold":{"rule":"required","type":"sint32","id":2}}},"AuthCreate":{"fields":{"byzcoin":{"rule":"required","type":"AuthCreateByzcoin","id":1},"x509cert":{"rule":"required","type":"AuthCreateX509Cert","id":2}}},"AuthCreateByzcoin":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"ltsinstance":{"rule":"required","type":"bytes","id":2}}},"AuthCreateX509Cert":{"fields":{"certificates":{"rule":"repeated","type":"bytes","id":1}}},"AuthReencrypt":{"fields":{"ephemeral":{"rule":"required","type":"bytes","id":1},"byzcoin":{"type":"AuthReencryptByzCoin","id":2},"x509cert":{"type":"AuthReencryptX509Cert","id":3}}},"AuthReencryptByzCoin":{"fields":{"write":{"rule":"required","type":"bytes","id":1},"read":{"rule":"required","type":"bytes","id":2},"ephemeral":{"rule":"required","type":"bytes","id":3},"signature":{"type":"darc.Signature","id":4}}},"AuthReencryptX509Cert":{"fields":{"u":{"rule":"required","type":"bytes","id":1},"certificates":{"rule":"repeated","type":"bytes","id":2}}},"AuthReshare":{"fields":{"byzcoin":{"type":"AuthReshareByzCoin","id":1},"x509cert":{"type":"AuthReshareX509Cert","id":2}}},"AuthReshareByzCoin":{"fields":{"reshare":{"rule":"required","type":"bytes","id":1}}},"AuthReshareX509Cert":{"fields":{"certificates":{"rule":"repeated","type":"bytes","id":1}}},"OCSProof":{"fields":{"ocsid":{"rule":"required","type":"bytes","id":1},"roster":{"rule":"required","type":"onet.Roster","id":2},"policyreencrypt":{"rule":"required","type":"Policy","id":3},"policyreshare":{"rule":"required","type":"Policy","id":4},"signatures":{"rule":"repeated","type":"bytes","id":5}}}}},"personhood":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"Personhood"},"nested":{"PartyList":{"fields":{"newparty":{"type":"Party","id":1},"wipeparties":{"type":"bool","id":2}}},"PartyListResponse":{"fields":{"parties":{"rule":"repeated","type":"Party","id":1,"options":{"packed":false}}}},"Party":{"fields":{"roster":{"rule":"required","type":"onet.Roster","id":1},"byzcoinid":{"rule":"required","type":"bytes","id":2},"instanceid":{"rule":"required","type":"bytes","id":3}}},"RoPaSciList":{"fields":{"newropasci":{"type":"RoPaSci","id":1},"wipe":{"type":"bool","id":2}}},"RoPaSciListResponse":{"fields":{"ropascis":{"rule":"repeated","type":"RoPaSci","id":1,"options":{"packed":false}}}},"RoPaSci":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"ropasciid":{"rule":"required","type":"bytes","id":2}}},"StringReply":{"fields":{"reply":{"rule":"required","type":"string","id":1}}},"RoPaSciStruct":{"fields":{"description":{"rule":"required","type":"string","id":1},"stake":{"rule":"required","type":"byzcoin.Coin","id":2},"firstplayerhash":{"rule":"required","type":"bytes","id":3},"firstplayer":{"type":"sint32","id":4},"secondplayer":{"type":"sint32","id":5},"secondplayeraccount":{"type":"bytes","id":6}}},"CredentialStruct":{"fields":{"credentials":{"rule":"repeated","type":"Credential","id":1,"options":{"packed":false}}}},"Credential":{"fields":{"name":{"rule":"required","type":"string","id":1},"attributes":{"rule":"repeated","type":"Attribute","id":2,"options":{"packed":false}}}},"Attribute":{"fields":{"name":{"rule":"required","type":"string","id":1},"value":{"rule":"required","type":"bytes","id":2}}},"SpawnerStruct":{"fields":{"costdarc":{"rule":"required","type":"byzcoin.Coin","id":1},"costcoin":{"rule":"required","type":"byzcoin.Coin","id":2},"costcredential":{"rule":"required","type":"byzcoin.Coin","id":3},"costparty":{"rule":"required","type":"byzcoin.Coin","id":4},"beneficiary":{"rule":"required","type":"bytes","id":5},"costropasci":{"type":"byzcoin.Coin","id":6}}},"PopPartyStruct":{"fields":{"state":{"rule":"required","type":"sint32","id":1},"organizers":{"rule":"required","type":"sint32","id":2},"finalizations":{"rule":"repeated","type":"string","id":3},"description":{"rule":"required","type":"PopDesc","id":4},"attendees":{"rule":"required","type":"Attendees","id":5},"miners":{"rule":"repeated","type":"LRSTag","id":6,"options":{"packed":false}},"miningreward":{"rule":"required","type":"uint64","id":7},"previous":{"type":"bytes","id":8},"next":{"type":"bytes","id":9}}},"PopDesc":{"fields":{"name":{"rule":"required","type":"string","id":1},"purpose":{"rule":"required","type":"string","id":2},"datetime":{"rule":"required","type":"uint64","id":3},"location":{"rule":"required","type":"string","id":4}}},"FinalStatement":{"fields":{"desc":{"type":"PopDesc","id":1},"attendees":{"rule":"required","type":"Attendees","id":2}}},"Attendees":{"fields":{"keys":{"rule":"repeated","type":"bytes","id":1}}},"LRSTag":{"fields":{"tag":{"rule":"required","type":"bytes","id":1}}},"Poll":{"fields":{"byzcoinid":{"rule":"required","type":"bytes","id":1},"newpoll":{"type":"PollStruct","id":2},"list":{"type":"PollList","id":3},"answer":{"type":"PollAnswer","id":4}}},"PollList":{"fields":{"partyids":{"rule":"repeated","type":"bytes","id":1}}},"PollAnswer":{"fields":{"pollid":{"rule":"required","type":"bytes","id":1},"choice":{"rule":"required","type":"sint32","id":2},"lrs":{"rule":"required","type":"bytes","id":3}}},"PollStruct":{"fields":{"personhood":{"rule":"required","type":"bytes","id":1},"pollid":{"type":"bytes","id":2},"title":{"rule":"required","type":"string","id":3},"description":{"rule":"required","type":"string","id":4},"choices":{"rule":"repeated","type":"string","id":5},"chosen":{"rule":"repeated","type":"PollChoice","id":6,"options":{"packed":false}}}},"PollChoice":{"fields":{"choice":{"rule":"required","type":"sint32","id":1},"lrstag":{"rule":"required","type":"bytes","id":2}}},"PollResponse":{"fields":{"polls":{"rule":"repeated","type":"PollStruct","id":1,"options":{"packed":false}}}},"Capabilities":{"fields":{}},"CapabilitiesResponse":{"fields":{"capabilities":{"rule":"repeated","type":"Capability","id":1,"options":{"packed":false}}}},"Capability":{"fields":{"endpoint":{"rule":"required","type":"string","id":1},"version":{"rule":"required","type":"bytes","id":2}}},"UserLocation":{"fields":{"publickey":{"rule":"required","type":"bytes","id":1},"credentialiid":{"type":"bytes","id":2},"credential":{"type":"CredentialStruct","id":3},"location":{"type":"string","id":4},"time":{"rule":"required","type":"sint64","id":5}}},"Meetup":{"fields":{"userlocation":{"type":"UserLocation","id":1},"wipe":{"type":"bool","id":2}}},"MeetupResponse":{"fields":{"users":{"rule":"repeated","type":"UserLocation","id":1,"options":{"packed":false}}}}}},"status":{"options":{"java_package":"ch.epfl.dedis.lib.proto","java_outer_classname":"StatusProto"},"nested":{"Request":{"fields":{}},"Response":{"fields":{"status":{"keyType":"string","type":"onet.Status","id":1},"serveridentity":{"type":"network.ServerIdentity","id":2}}}}}}} \ No newline at end of file diff --git a/external/proto/calypso.proto b/external/proto/calypso.proto index bfe987dcbb..af6b2c8d52 100644 --- a/external/proto/calypso.proto +++ b/external/proto/calypso.proto @@ -28,8 +28,9 @@ message Write { // f is the proof - written in uppercase here so it is an exported // field, but in the OCS-paper it's lowercase. required bytes f = 5; - // C is the ElGamal parts for the symmetric key material (might also - // contain an IV) + // C is the ElGamal part for the symmetric key material, at maximum length + // of ed25519.Point.EmbedLen * 8 = 240 bits. An eventual IV must be published + // in ExtraData, as it is not necessary to be encrypted. required bytes c = 6; // ExtraData is clear text and application-specific optional bytes extradata = 7; @@ -58,7 +59,7 @@ message Authorise { message AuthoriseReply { } -// CreateLTS is used to start a DKG and store the private keys in each node. +// CreateOCS is used to start a DKG and store the private keys in each node. // Prior to using this request, the Calypso roster must be recorded on the // ByzCoin blockchain in the instance specified by InstanceID. message CreateLTS { @@ -86,7 +87,7 @@ message ReshareLTS { message ReshareLTSReply { } -// DecryptKey is sent by a reader after he successfully stored a 'Read' request +// Reencrypt is sent by a reader after he successfully stored a 'Read' request // in byzcoin Client. message DecryptKey { // Read is the proof that he has been accepted to read the secret. diff --git a/external/proto/ocs.proto b/external/proto/ocs.proto index ab6dc1d8ca..f208a174d4 100644 --- a/external/proto/ocs.proto +++ b/external/proto/ocs.proto @@ -1,6 +1,7 @@ syntax = "proto2"; package ocs; import "onet.proto"; +import "darc.proto"; option java_package = "ch.epfl.dedis.lib.proto"; option java_outer_classname = "OCS"; @@ -9,10 +10,28 @@ option java_outer_classname = "OCS"; // API calls // *** +// AddPolicyCreateOCS is sent by a local admin to add a rule to define who is +// authorized to create a new OCS. +message AddPolicyCreateOCS { + required Policy create = 1; +} + +// AddPolicyCreateOCSReply is an empty reply if the policy has been successfully +// created. +message AddPolicyCreateOCSReply { +} + // CreateOCS is sent to the service to request a new OCS cothority. +// It holds the two policies necessary to define an OCS: how to +// authenticate a reencryption request, and how to authenticate a +// resharing request. +// In the current form, both policies point to the same structure. If at +// a later moment a new access control backend is added, it might be that +// the policies will differ for this new backend. message CreateOCS { required onet.Roster roster = 1; - required Policy policy = 2; + required Policy policyreencrypt = 2; + required Policy policyreshare = 3; } // CreateOCSReply is the reply sent by the conode if the OCS has been @@ -21,8 +40,19 @@ message CreateOCS { // is the collective signature of all nodes on the aggregate public key // and the authentication. message CreateOCSReply { - required bytes x = 1; - required bytes sig = 2; + required bytes ocsid = 1; +} + +// GetProof is sent to a node to have him sign his definition of the +// given OCS. +message GetProof { + required bytes ocsid = 1; +} + +// GetProofReply contains the additional info that node has on the given +// OCS, as well as a signature using the services private key. +message GetProofReply { + required OCSProof proof = 1; } // Reencrypt is sent to the service to request a re-encryption of the @@ -30,7 +60,7 @@ message CreateOCSReply { // request is valid, as well as the ephemeral key, to which the secret // will be re-encrypted. message Reencrypt { - required bytes x = 1; + required bytes ocsid = 1; required AuthReencrypt auth = 2; } @@ -38,14 +68,18 @@ message Reencrypt { // it contains XHat, which is the secret re-encrypted to the ephemeral // key given in AuthReencrypt. message ReencryptReply { - required bytes xhat = 1; + required bytes x = 1; + required bytes xhatenc = 2; + required bytes c = 3; } // Reshare is called to ask OCS to change the roster. It needs a valid -// authentication before the private keys are re-generated over the new +// authentication before the private keys are re-distributed over the new // roster. +// TODO: should NewRoster be always present in AuthReshare? It will be present +// TODO: at least in AuthReshareByzCoin, but might not in other AuthReshares message Reshare { - required bytes x = 1; + required bytes ocsid = 1; required onet.Roster newroster = 2; required AuthReshare auth = 3; } @@ -61,22 +95,11 @@ message ReshareReply { // Common structures // *** -// PolicyOCS holds the two policies necessary to define an OCS: how to -// authenticate a reencryption request, and how to authenticate a -// resharing request. -// In the current form, both policies point to the same structure. If at -// a later moment a new access control backend is added, it might be that -// the policies will differ for this new backend. -message PolicyOCS { - required Policy policyreencrypt = 1; - required Policy policyreshare = 2; -} - // Policy holds all possible authentication structures. When using it to call // Authorise, only one of the fields must be non-nil. message Policy { optional PolicyByzCoin byzcoin = 1; - optional PolicyX509Cert authx509cert = 2; + optional PolicyX509Cert x509cert = 2; } // PolicyByzCoin holds the information necessary to authenticate a byzcoin request. @@ -88,7 +111,7 @@ message PolicyByzCoin { required uint64 ttl = 2; } -// PolicyX509Cert holds the information necessary to authenticate a HyperLedger/Fabric +// X509Cert holds the information necessary to authenticate a HyperLedger/Fabric // request. In its simplest form, it is simply the CA that will have to sign the // certificates of the requesters. // The Threshold indicates how many clients must have signed the request before it @@ -99,13 +122,34 @@ message PolicyX509Cert { required sint32 threshold = 2; } +// AuthCreate prooves that the caller has the right to create a new OCS +// instance. +message AuthCreate { + required AuthCreateByzcoin byzcoin = 1; + required AuthCreateX509Cert x509cert = 2; +} + +// AuthCreateByzcoin must give the ByzcoinID and the proof to the LTSInstance +// for the creation of a new OCS. +message AuthCreateByzcoin { + required bytes byzcoinid = 1; + required bytes ltsinstance = 2; +} + +// AuthCreateX509Cert must give a threshold number of certificates to proof that +// the caller has the right to create a new OCS. +message AuthCreateX509Cert { + repeated bytes certificates = 1; +} + // AuthReencrypt holds one of the possible authentication proofs for a reencryption request. Each // authentication proof must hold the secret to be reencrypted, the ephemeral key, as well // as the proof itself that the request is valid. For each of the authentication // schemes, this proof will be different. message AuthReencrypt { - optional AuthReencryptByzCoin byzcoin = 1; - optional AuthReencryptX509Cert x509cert = 2; + required bytes ephemeral = 1; + optional AuthReencryptByzCoin byzcoin = 2; + optional AuthReencryptX509Cert x509cert = 3; } // AuthReencryptByzCoin holds the proof of the write instance, holding the secret itself. @@ -116,16 +160,22 @@ message AuthReencryptByzCoin { required bytes write = 1; // Read is the proof that he has been accepted to read the secret. required bytes read = 2; + // Ephemeral can be non-nil to point to a key to which the data needs to be + // re-encrypted to, but then Signature also needs to be non-nil. + required bytes ephemeral = 3; + // If Ephemeral si non-nil, it must be signed by the darc responsible for the + // Read instance to make sure it's a valid reencryption-request. + optional darc.Signature signature = 4; } // AuthReencryptX509Cert holds the proof that at least a threshold number of clients // accepted the reencryption. // For each client, there must exist a certificate that can be verified by the -// CA certificate from PolicyX509Cert. Additionally, each client must sign the +// CA certificate from X509Cert. Additionally, each client must sign the // following message: // sha256( Secret | Ephemeral | Time ) message AuthReencryptX509Cert { - required bytes secret = 1; + required bytes u = 1; repeated bytes certificates = 2; } @@ -148,3 +198,12 @@ message AuthReshareByzCoin { message AuthReshareX509Cert { repeated bytes certificates = 1; } + +// OCSProof can be used to proof +message OCSProof { + required bytes ocsid = 1; + required onet.Roster roster = 2; + required Policy policyreencrypt = 3; + required Policy policyreshare = 4; + repeated bytes signatures = 5; +} diff --git a/ocs/proto.go b/ocs/proto.go index 0f9c5fc567..ea787f5e85 100644 --- a/ocs/proto.go +++ b/ocs/proto.go @@ -18,6 +18,7 @@ import ( // type :OCSID:bytes // package ocs; // import "onet.proto"; +// import "darc.proto"; // // option java_package = "ch.epfl.dedis.lib.proto"; // option java_outer_classname = "OCS"; diff --git a/proto.sh b/proto.sh index 8bd8d7df1c..562658fe12 100755 --- a/proto.sh +++ b/proto.sh @@ -6,7 +6,7 @@ set -u struct_files=(`find . -name proto.go | sort`) pv=`protoc --version` -if [ "$pv" != "libprotoc 3.6.1" and "$pv" != "libprotoc 3.7.1"]; then +if [ "$pv" != "libprotoc 3.6.1" -a "$pv" != "libprotoc 3.7.1" ]; then echo "Protoc version $pv is not supported. Please install 3.6.1 or 3.7.1" exit 1 fi From 0340c873173535bcb508bc32fbbdeb6c511ce272 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Mon, 29 Apr 2019 16:58:46 +0200 Subject: [PATCH 17/21] Work on OCS module - removed 'C' from ocs.ReencryptReply - enable threshold > 1 for policies - change CA dependencies to have independent CAs for CreateOCS and Reencrypt policies - add AuthCreateOCS to ocs.CreateOCS call, which needs an ExtraExtension for the Policies - changed Policy to PolicyCreate, PolicyReencrypt, and PolicyReshare - correct use of PolicyReencrypt and PolicyReshare --- ocs/CHANGELOG.md | 7 ++ ocs/README.md | 12 ++- ocs/api.go | 17 +-- ocs/api_test.go | 45 ++++---- ocs/auth.go | 258 ++++++++++++++++++++++++++++++++++++++++++++ ocs/certs/helper.go | 97 ----------------- ocs/certs/verify.go | 130 ---------------------- ocs/certs/x509.go | 161 --------------------------- ocs/db.go | 6 +- ocs/demo/Makefile | 15 +++ ocs/demo/main.go | 80 ++++++++------ ocs/helper.go | 236 ++++++++++++++++++++++++++++++++++++++++ ocs/proto.go | 46 +++++--- ocs/service.go | 77 ++++++------- ocs/service_test.go | 158 ++++++++++++++++++--------- ocs/struct.go | 64 +---------- ocs/struct_test.go | 36 +++++++ 17 files changed, 823 insertions(+), 622 deletions(-) create mode 100644 ocs/CHANGELOG.md create mode 100644 ocs/auth.go delete mode 100644 ocs/certs/helper.go delete mode 100644 ocs/certs/verify.go delete mode 100644 ocs/certs/x509.go create mode 100644 ocs/demo/Makefile create mode 100644 ocs/helper.go create mode 100644 ocs/struct_test.go diff --git a/ocs/CHANGELOG.md b/ocs/CHANGELOG.md new file mode 100644 index 0000000000..8d84599582 --- /dev/null +++ b/ocs/CHANGELOG.md @@ -0,0 +1,7 @@ +- multi_sig - work on ocs-module (2019-04-30): + - removed 'C' from ocs.ReencryptReply + - enable threshold > 1 for policies + - change CA dependencies to have independent CAs for CreateOCS and Reencrypt policies + - add AuthCreateOCS to ocs.CreateOCS call, which needs an ExtraExtension for the Policies + - changed Policy to PolicyCreate, PolicyReencrypt, and PolicyReshare + - correct use of PolicyReencrypt and PolicyReshare \ No newline at end of file diff --git a/ocs/README.md b/ocs/README.md index fb76e4804d..c7390990f9 100644 --- a/ocs/README.md +++ b/ocs/README.md @@ -87,8 +87,8 @@ defined as follows: - `ByzCoin` - by giving a byzcoin-ID, CreateOCS will accept every proof of an LTSInstance that can be verified using a stored byzcoin-ID -- `X509Cert` - by giving a root-CA, CreateOCS will accept every request with -policies signed by this root-CA +- `X509Cert` - the CAs defined in this policy will be used to verify the +authentication ## CreateOCS @@ -98,8 +98,9 @@ ACCs is fulfilled: - `ByzCoin` - the proof given in the `Reencrypt` policy must be verifiable with one of the stored byzcoin-IDs -- `X509Cert` - the certificate given in `Reencrypt` and `Reshare` must have -been signed by one of the root-CAs +- `X509Cert` - a valid certificate signed by a threshold of CAs defined in +`AddPolicyCreateOCS` must be present. Each certificate must include the +`PolicyReencrypt`, `PolicyReshare`, and `Roster` The CreateOCS service endpoint returns a `LTSID` in the form of a 32 byte slice. This ID represents the group that created the distributed key. Any node @@ -130,4 +131,5 @@ steps. between themselves. For this operation, all nodes must be online. By default, a threshold of 2/3 of -the nodes must be present for the decryption. \ No newline at end of file +the nodes must be present for the decryption. + diff --git a/ocs/api.go b/ocs/api.go index 80e8543be4..9940527419 100644 --- a/ocs/api.go +++ b/ocs/api.go @@ -2,7 +2,6 @@ package ocs import ( "go.dedis.ch/cothority/v3" - "go.dedis.ch/cothority/v3/ocs/certs" "go.dedis.ch/kyber/v3" "go.dedis.ch/onet/v3" "go.dedis.ch/onet/v3/network" @@ -24,8 +23,11 @@ func NewClient() *Client { } // AddPolicyCreateOCS stores who is allowed to create new OCS instances. -func (c *Client) AddPolicyCreateOCS(si *network.ServerIdentity, policy Policy) error { - return c.SendProtobuf(si, &AddPolicyCreateOCS{Create: policy}, nil) +// +// This can only be called from localhost, except if the environment variable +// COTHORITY_ALLOW_INSECURE_ADMIN is set to 'true'. +func (c *Client) AddPolicyCreateOCS(si *network.ServerIdentity, policyCreate PolicyCreate) error { + return c.SendProtobuf(si, &AddPolicyCreateOCS{Create: policyCreate}, nil) } // CreateOCS starts a new Distributed Key Generation with the nodes in the roster and @@ -34,16 +36,15 @@ func (c *Client) AddPolicyCreateOCS(si *network.ServerIdentity, policy Policy) e // // It also sets up an authorisation option for the nodes. // -// This can only be called from localhost, except if the environment variable -// COTHORITY_ALLOW_INSECURE_ADMIN is set to 'true'. -// // In case of error, X is nil, and the error indicates what is wrong. // The `sig` returned is a collective signature on the following hash: // sha256( X | protobuf.Encode(auth) ) -func (c *Client) CreateOCS(roster onet.Roster, policyReencrypt, policyReshare Policy) (OcsID OCSID, err error) { +func (c *Client) CreateOCS(roster onet.Roster, auth AuthCreate, policyReencrypt PolicyReencrypt, + policyReshare PolicyReshare) (OcsID OCSID, err error) { var ret CreateOCSReply err = c.SendProtobuf(roster.List[0], &CreateOCS{ Roster: roster, + Auth: auth, PolicyReencrypt: policyReencrypt, PolicyReshare: policyReshare, }, &ret) @@ -62,7 +63,7 @@ func (c *Client) GetProofs(roster onet.Roster, OcsID OCSID) (op OCSProof, err er var reply GetProofReply err = c.SendProtobuf(si, &GetProof{OcsID}, &reply) if err != nil { - err = certs.Erret(err) + err = Erret(err) return } if len(op.Signatures) == 0 { diff --git a/ocs/api_test.go b/ocs/api_test.go index 93d5b56853..5d2907e62a 100644 --- a/ocs/api_test.go +++ b/ocs/api_test.go @@ -6,8 +6,6 @@ import ( "go.dedis.ch/cothority/v3" "go.dedis.ch/kyber/v3/util/key" - "go.dedis.ch/onet/v3/log" - "github.com/stretchr/testify/require" "go.dedis.ch/onet/v3" ) @@ -19,18 +17,16 @@ func TestClient_GetProofs(t *testing.T) { nbrNodes := 5 _, roster, _ := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) - _, caCert, err := CreateCertCa() - require.NoError(t, err) - - px := Policy{ - X509Cert: &PolicyX509Cert{ - CA: [][]byte{caCert.Raw}, - Threshold: 1, - }, - } + cc := newCaCerts(2, 1, 1) cl := NewClient() - oid, err := cl.CreateOCS(*roster, px, px) + for _, si := range roster.List { + err := cl.AddPolicyCreateOCS(si, cc.policyCreate) + require.NoError(t, err) + } + oid, err := cl.CreateOCS(*roster, cc.authCreate(1, *roster), cc.policyReencrypt, cc.policyReshare) + require.Error(t, err) + oid, err = cl.CreateOCS(*roster, cc.authCreate(2, *roster), cc.policyReencrypt, cc.policyReshare) require.NoError(t, err) op, err := cl.GetProofs(*roster, oid) @@ -45,21 +41,17 @@ func TestClient_Reencrypt(t *testing.T) { nbrNodes := 5 _, roster, _ := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) - caPrivKey, caCert, err := CreateCertCa() - require.NoError(t, err) - log.Lvl5(caPrivKey) - - px := Policy{ - X509Cert: &PolicyX509Cert{ - CA: [][]byte{caCert.Raw}, - Threshold: 1, - }, - } + cc := newCaCerts(1, 2, 2) cl := NewClient() + for _, si := range roster.List { + err := cl.AddPolicyCreateOCS(si, cc.policyCreate) + require.NoError(t, err) + } var oid OCSID + var err error for i := 0; i < 10; i++ { - oid, err = cl.CreateOCS(*roster, px, px) + oid, err = cl.CreateOCS(*roster, cc.authCreate(1, *roster), cc.policyReencrypt, cc.policyReshare) require.NoError(t, err) } @@ -72,15 +64,16 @@ func TestClient_Reencrypt(t *testing.T) { kp := key.NewKeyPair(cothority.Suite) wid, err := NewWriteID(X, U) require.NoError(t, err) - reencryptCert, err := CreateCertReencrypt(caCert, caPrivKey, wid, kp.Public) - require.NoError(t, err) auth := AuthReencrypt{ Ephemeral: kp.Public, X509Cert: &AuthReencryptX509Cert{ U: U, - Certificates: [][]byte{reencryptCert.Raw}, + Certificates: cc.authReencrypt(1, wid, kp.Public), }, } + _, err = cl.Reencrypt(*roster, oid, auth) + require.Error(t, err) + auth.X509Cert.Certificates = cc.authReencrypt(2, wid, kp.Public) for i := 0; i < 10; i++ { XhatEnc, err := cl.Reencrypt(*roster, oid, auth) require.NoError(t, err) diff --git a/ocs/auth.go b/ocs/auth.go new file mode 100644 index 0000000000..83464e31e5 --- /dev/null +++ b/ocs/auth.go @@ -0,0 +1,258 @@ +package ocs + +import ( + "bytes" + "crypto/sha256" + "crypto/x509" + "encoding/asn1" + "errors" + "strings" + + "go.dedis.ch/cothority/v3" + "go.dedis.ch/protobuf" + + "go.dedis.ch/onet/v3" + + "go.dedis.ch/kyber/v3" +) + +func (cocs CreateOCS) verifyAuth(policies []PolicyCreate) error { + for _, p := range policies { + if err := p.verify(cocs.Auth, cocs.PolicyReencrypt, cocs.PolicyReshare, cocs.Roster); err == nil { + return nil + } + } + return errors.New("no policy matches against the authorization") +} + +func (pc PolicyCreate) verify(auth AuthCreate, pRC PolicyReencrypt, pRS PolicyReshare, roster onet.Roster) error { + if pc.X509Cert != nil && auth.X509Cert != nil && pRC.X509Cert != nil && pRS.X509Cert != nil { + return pc.X509Cert.verify(auth.X509Cert.Certificates, func(vo x509.VerifyOptions, cert *x509.Certificate) error { + return VerifyCreate(vo, cert, pRC.X509Cert, pRS.X509Cert, roster) + }) + } + if pc.ByzCoin != nil && auth.ByzCoin != nil && pRC.ByzCoin != nil && pRS.ByzCoin != nil { + return errors.New("byzcoin verification not implemented yet") + } + return errors.New("no matching policy/auth found") +} + +func (pc PolicyReencrypt) verify(auth AuthReencrypt, X, U kyber.Point) error { + if X == nil || U == nil { + return errors.New("need both X and U for verification") + } + if pc.X509Cert != nil && auth.X509Cert != nil { + return pc.X509Cert.verify(auth.X509Cert.Certificates, func(vo x509.VerifyOptions, cert *x509.Certificate) error { + return VerifyReencrypt(vo, cert, X, U) + }) + } + if pc.ByzCoin != nil && auth.ByzCoin != nil { + return errors.New("byzcoin verification not implemented yet") + } + return errors.New("no matching policy/auth found") +} + +func (pc PolicyReshare) verify(auth AuthReshare, r onet.Roster) error { + if len(r.List) < 2 { + return errors.New("roster must have at least 2 nodes") + } + if pc.X509Cert != nil && auth.X509Cert != nil { + return pc.X509Cert.verify(auth.X509Cert.Certificates, func(vo x509.VerifyOptions, cert *x509.Certificate) error { + return VerifyReshare(vo, cert, r) + }) + } + if pc.ByzCoin != nil && auth.ByzCoin != nil { + return errors.New("byzcoin verification not implemented yet") + } + return errors.New("no matching policy/auth found") +} + +type verifyFunc func(vo x509.VerifyOptions, cert *x509.Certificate) error + +func (p509 PolicyX509Cert) verify(certBufs [][]byte, vf verifyFunc) error { + var certs []*x509.Certificate + for _, certBuf := range certBufs { + cert, err := x509.ParseCertificate(certBuf) + if err != nil { + return err + } + certs = append(certs, cert) + } + count := 0 + var errs []string + for _, caBuf := range p509.CA { + ca, err := x509.ParseCertificate(caBuf) + if err != nil { + return err + } + roots := x509.NewCertPool() + roots.AddCert(ca) + opt := x509.VerifyOptions{Roots: roots} + for _, cert := range certs { + if err := vf(opt, cert); err == nil { + count++ + break + } else { + errs = append(errs, err.Error()) + } + } + } + if count >= p509.Threshold { + return nil + } + return errors.New("didn't reach threshold - errs: " + strings.Join(errs, "\n -- ")) +} + +var ( + // selection of OID numbers is not random See documents + // https://tools.ietf.org/html/rfc5280#page-49 + // https://tools.ietf.org/html/rfc7229 + OIDWriteId = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 1} + OIDEphemeralKey = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 2} + OIDPolicyReencrypt = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 3} + OIDPolicyReshare = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 4} + OIDRoster = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 5} +) + +// VerifyReencrypt takes a root certificate and the certificate to verify. It then verifies +// the certificates with regard to the signature of the root-certificate to the +// authCert. +// ocsID is the ID of the LTS cothority, while U is the commitment to the secret. +func VerifyReencrypt(vo x509.VerifyOptions, cert *x509.Certificate, X kyber.Point, U kyber.Point) (err error) { + wid, err := GetExtensionFromCert(cert, OIDWriteId) + if err != nil { + return Erret(err) + } + err = WriteID(wid).Verify(X, U) + if err != nil { + return Erret(err) + } + + unmarkUnhandledCriticalExtension(cert, OIDWriteId) + unmarkUnhandledCriticalExtension(cert, OIDEphemeralKey) + + _, err = cert.Verify(vo) + return Erret(err) +} + +// VerifyCreate takes a root certificate and the certificate to verify. It then verifies +// the certificates with regard to the signature of the root-certificate to the +// authCert. +// ocsID is the ID of the LTS cothority, while U is the commitment to the secret. +func VerifyCreate(vo x509.VerifyOptions, cert *x509.Certificate, policyReencrypt, policyReshare *PolicyX509Cert, + roster onet.Roster) (err error) { + pRcBuf, err := GetExtensionFromCert(cert, OIDPolicyReencrypt) + if err != nil { + return Erret(err) + } + pBuf, err := protobuf.Encode(policyReencrypt) + if err != nil { + return Erret(err) + } + if bytes.Compare(pRcBuf, pBuf) != 0 { + return errors.New("reencryption-policy doesn't match policy in certificate") + } + + pRsBuf, err := GetExtensionFromCert(cert, OIDPolicyReshare) + if err != nil { + return Erret(err) + } + pBuf, err = protobuf.Encode(policyReshare) + if err != nil { + return Erret(err) + } + if bytes.Compare(pRsBuf, pBuf) != 0 { + return errors.New("reshare-policy doesn't match policy in certificate") + } + + rosterBuf, err := GetExtensionFromCert(cert, OIDRoster) + if err != nil { + return Erret(err) + } + rBuf, err := protobuf.Encode(&roster) + if err != nil { + return Erret(err) + } + if bytes.Compare(rosterBuf, rBuf) != 0 { + return errors.New("roster doesn't match roster in certificate") + } + + unmarkUnhandledCriticalExtension(cert, OIDPolicyReencrypt) + unmarkUnhandledCriticalExtension(cert, OIDPolicyReshare) + unmarkUnhandledCriticalExtension(cert, OIDRoster) + + _, err = cert.Verify(vo) + return Erret(err) +} + +func VerifyReshare(vo x509.VerifyOptions, cert *x509.Certificate, r onet.Roster) (err error) { + return errors.New("reshare verification not yet implemented") +} + +// WriteID is the ID that will be revealed to the X509 verification method. +type WriteID []byte + +func NewWriteID(X, U kyber.Point) (WriteID, error) { + if X == nil || U == nil { + return nil, errors.New("X or U is missing") + } + wid := sha256.New() + _, err := X.MarshalTo(wid) + if err != nil { + return nil, Erret(err) + } + _, err = U.MarshalTo(wid) + if err != nil { + return nil, Erret(err) + } + return wid.Sum(nil), nil +} + +func (wid WriteID) Verify(X, U kyber.Point) error { + other, err := NewWriteID(X, U) + if err != nil { + return Erret(err) + } + if bytes.Compare(wid, other) != 0 { + return errors.New("not the same writeID") + } + return nil +} + +func GetPointFromCert(certBuf []byte, extID asn1.ObjectIdentifier) (kyber.Point, error) { + cert, err := x509.ParseCertificate(certBuf) + if err != nil { + return nil, Erret(err) + } + secret := cothority.Suite.Point() + secretBuf, err := GetExtensionFromCert(cert, extID) + if err != nil { + return nil, Erret(err) + } + err = secret.UnmarshalBinary(secretBuf) + return secret, Erret(err) +} + +func GetExtensionFromCert(cert *x509.Certificate, extID asn1.ObjectIdentifier) ([]byte, error) { + var buf []byte + for _, ext := range cert.Extensions { + if ext.Id.Equal(extID) { + buf = ext.Value + break + } + } + if buf == nil { + return nil, errors.New("didn't find extension in certificate") + } + return buf, nil +} + +func unmarkUnhandledCriticalExtension(cert *x509.Certificate, id asn1.ObjectIdentifier) { + for i, extension := range cert.UnhandledCriticalExtensions { + if id.Equal(extension) { + cert.UnhandledCriticalExtensions = append(cert.UnhandledCriticalExtensions[0:i], + cert.UnhandledCriticalExtensions[i+1:]...) + return + } + } +} diff --git a/ocs/certs/helper.go b/ocs/certs/helper.go deleted file mode 100644 index 528dc0ad15..0000000000 --- a/ocs/certs/helper.go +++ /dev/null @@ -1,97 +0,0 @@ -package certs - -import ( - "errors" - "fmt" - "runtime" - "strings" - - "go.dedis.ch/kyber/v3" - "go.dedis.ch/kyber/v3/suites" - "go.dedis.ch/onet/v3/log" -) - -// EncodeKey can be used by the writer to an onchain-secret skipchain -// to encode his symmetric key under the collective public key created -// by the DKG. -// As this method uses `Pick` to encode the key, depending on the key-length -// more than one point is needed to encode the data. -// -// Input: -// - suite - the cryptographic suite to use -// - X - the aggregate public key of the DKG -// - key - the symmetric key for the document -// -// Output: -// - U - the schnorr commit -// - C - encrypted key -func EncodeKey(suite suites.Suite, X kyber.Point, key []byte) (U kyber.Point, C kyber.Point, err error) { - if len(key) > suite.Point().EmbedLen() { - return nil, nil, errors.New("got more data than can fit into one point") - } - r := suite.Scalar().Pick(suite.RandomStream()) - C = suite.Point().Mul(r, X) - log.Lvl3("C:", C.String()) - U = suite.Point().Mul(r, nil) - log.Lvl3("U is:", U.String()) - - kp := suite.Point().Embed(key, suite.RandomStream()) - log.Lvl3("Keypoint:", kp.String()) - log.Lvl3("X:", X.String()) - C.Add(C, kp) - return -} - -// DecodeKey can be used by the reader of an onchain-secret to convert the -// re-encrypted secret back to a symmetric key that can be used later to -// decode the document. -// -// Input: -// - suite - the cryptographic suite to use -// - X - the aggregate public key of the DKG -// - C - the encrypted key -// - XhatEnc - the re-encrypted schnorr-commit -// - xc - the private key of the reader -// -// Output: -// - key - the re-assembled key -// - err - an eventual error when trying to recover the data from the points -func DecodeKey(suite kyber.Group, X kyber.Point, C kyber.Point, XhatEnc kyber.Point, - xc kyber.Scalar) (key []byte, err error) { - log.Lvl3("xc:", xc) - xcInv := suite.Scalar().Neg(xc) - log.Lvl3("xcInv:", xcInv) - sum := suite.Scalar().Add(xc, xcInv) - log.Lvl3("xc + xcInv:", sum, "::", xc) - log.Lvl3("X:", X) - XhatDec := suite.Point().Mul(xcInv, X) - log.Lvl3("XhatDec:", XhatDec) - log.Lvl3("XhatEnc:", XhatEnc) - Xhat := suite.Point().Add(XhatEnc, XhatDec) - log.Lvl3("Xhat:", Xhat) - XhatInv := suite.Point().Neg(Xhat) - log.Lvl3("XhatInv:", XhatInv) - - // Decrypt C to keyPointHat - log.Lvl3("C:", C) - keyPointHat := suite.Point().Add(C, XhatInv) - log.Lvl3("keyPointHat:", keyPointHat) - key, err = keyPointHat.Data() - if err != nil { - return nil, Erret(err) - } - log.Lvl3("key:", key) - return -} - -func Erret(err error) error { - if err == nil { - return nil - } - pc, _, line, _ := runtime.Caller(1) - errStr := err.Error() - if strings.HasPrefix(errStr, "Erret") { - errStr = "\n\t" + errStr - } - return fmt.Errorf("Erret at %s: %d -> %s", runtime.FuncForPC(pc).Name(), line, errStr) -} diff --git a/ocs/certs/verify.go b/ocs/certs/verify.go deleted file mode 100644 index bb02c6c222..0000000000 --- a/ocs/certs/verify.go +++ /dev/null @@ -1,130 +0,0 @@ -package certs - -import ( - "bytes" - "crypto/sha256" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "errors" - - "go.dedis.ch/cothority/v3" - "go.dedis.ch/kyber/v3" -) - -var ( - // selection of OID numbers is not random See documents - // https://tools.ietf.org/html/rfc5280#page-49 - // https://tools.ietf.org/html/rfc7229 - WriteIdOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 1} - EphemeralKeyOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 13, 2} -) - -// Verify takes a root certificate and the certificate to verify. It then verifies -// the certificates with regard to the signature of the root-certificate to the -// authCert. -// ocsID is the ID of the LTS cothority, while U is the commitment to the secret. -func Verify(rootCert *x509.Certificate, authCert *x509.Certificate, X kyber.Point, U kyber.Point) (err error) { - roots := x509.NewCertPool() - roots.AddCert(rootCert) - - cert, err := x509.ParseCertificate(authCert.Raw) - if err != nil { - return Erret(err) - } - - opts := x509.VerifyOptions{ - Roots: roots, - } - - wid, err := GetExtensionFromCert(authCert, WriteIdOID) - if err != nil { - return Erret(err) - } - err = WriteID(wid).Verify(X, U) - if err != nil { - return Erret(err) - } - - unmarkUnhandledCriticalExtension(cert, WriteIdOID) - unmarkUnhandledCriticalExtension(cert, EphemeralKeyOID) - - _, err = cert.Verify(opts) - return Erret(err) -} - -// WriteID is the ID that will be revealed to the X509 verification method. -type WriteID []byte - -func NewWriteID(X, U kyber.Point) (WriteID, error) { - wid := sha256.New() - _, err := X.MarshalTo(wid) - if err != nil { - return nil, Erret(err) - } - _, err = U.MarshalTo(wid) - if err != nil { - return nil, Erret(err) - } - return wid.Sum(nil), nil -} - -func (wid WriteID) Verify(X, U kyber.Point) error { - other, err := NewWriteID(X, U) - if err != nil { - return Erret(err) - } - if bytes.Compare(wid, other) != 0 { - return errors.New("not the same writeID") - } - return nil -} - -func GetPointFromCert(certBuf []byte, extID asn1.ObjectIdentifier) (kyber.Point, error) { - cert, err := x509.ParseCertificate(certBuf) - if err != nil { - return nil, Erret(err) - } - secret := cothority.Suite.Point() - secretBuf, err := GetExtensionFromCert(cert, extID) - if err != nil { - return nil, Erret(err) - } - err = secret.UnmarshalBinary(secretBuf) - return secret, Erret(err) -} - -func GetExtensionFromCert(cert *x509.Certificate, extID asn1.ObjectIdentifier) ([]byte, error) { - var buf []byte - for _, ext := range cert.Extensions { - if ext.Id.Equal(extID) { - buf = ext.Value - break - } - } - if buf == nil { - return nil, errors.New("didn't find extension in certificate") - } - return buf, nil -} - -func unmarkUnhandledCriticalExtension(cert *x509.Certificate, id asn1.ObjectIdentifier) { - for i, extension := range cert.UnhandledCriticalExtensions { - if id.Equal(extension) { - cert.UnhandledCriticalExtensions = append(cert.UnhandledCriticalExtensions[0:i], - cert.UnhandledCriticalExtensions[i+1:]...) - return - } - } -} - -func getExtension(certificate *x509.Certificate, id asn1.ObjectIdentifier) *pkix.Extension { - - for _, ext := range certificate.Extensions { - if ext.Id.Equal(id) { - return &ext - } - } - - return nil -} diff --git a/ocs/certs/x509.go b/ocs/certs/x509.go deleted file mode 100644 index 36efc6c9c9..0000000000 --- a/ocs/certs/x509.go +++ /dev/null @@ -1,161 +0,0 @@ -package certs - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/x509" - "crypto/x509/pkix" - "math/big" - "time" - - "go.dedis.ch/kyber/v3" -) - -// Helper functions to create x509-certificates. They are supposed to be used in the following -// way: -// -// CertCa - is the basic certificate that can create CertNodes -// +-> CertNode - can be given as a CA for Reencryption and Resharing -// +-> CertReencrypt - indicates who is allowed to reencrypt and gives the ephemeral key - -// CreateCertCa is used for tests and returns a new private key, as well as a CA certificate. -func CreateCertCa() (caPrivKey *ecdsa.PrivateKey, cert *x509.Certificate, err error) { - notBefore := time.Now() - notAfter := notBefore.Add(25 * 365 * 24 * time.Hour) - serialNumber := big.NewInt(1) - - template := x509.Certificate{ - SerialNumber: serialNumber, - Subject: pkix.Name{ - CommonName: "ByzGen signer org1", - }, - NotBefore: notBefore, - NotAfter: notAfter, - - KeyUsage: x509.KeyUsageCertSign, - BasicConstraintsValid: true, - MaxPathLen: 2, - IsCA: true, - } - caPrivKey, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) - if err != nil { - return nil, nil, Erret(err) - } - derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &caPrivKey.PublicKey, caPrivKey) - if err != nil { - return nil, nil, Erret(err) - } - - cert, err = x509.ParseCertificate(derBytes) - if err != nil { - return nil, nil, Erret(err) - } - return -} - -// CreateCertNode is used for tests and can create a certificate for one of the nodes. -func CreateCertNode(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey) ( - nodePrivKey *ecdsa.PrivateKey, nodeCert *x509.Certificate, err error) { - - notBefore := time.Now() - // 10 years for a node certificate - notAfter := notBefore.Add(31e6 * 10 * time.Second) - - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) - serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) - if err != nil { - return nil, nil, Erret(err) - } - - template := x509.Certificate{ - SerialNumber: serialNumber, - Subject: pkix.Name{ - CommonName: "Node certificate", - }, - NotBefore: notBefore, - NotAfter: notAfter, - - KeyUsage: x509.KeyUsageCertSign, - MaxPathLen: 1, - BasicConstraintsValid: true, - IsCA: true, - } - - nodePrivKey, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) - if err != nil { - return nil, nil, Erret(err) - } - derBytes, err := x509.CreateCertificate(rand.Reader, &template, caCert, &nodePrivKey.PublicKey, caPrivKey) - if err != nil { - return nil, nil, Erret(err) - } - - nodeCert, err = x509.ParseCertificate(derBytes) - if err != nil { - return nil, nil, Erret(err) - } - - return -} - -// CreateCertReencrypt is used for tests and can create a certificate for a reencryption request. -func CreateCertReencrypt(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, - writeID []byte, ephemeralPublicKey kyber.Point) (*x509.Certificate, error) { - - notBefore := time.Now() - notAfter := notBefore.Add(14 * 24 * time.Hour) - - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) - serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) - if err != nil { - return nil, Erret(err) - } - - writeIdExt := pkix.Extension{ - Id: WriteIdOID, - Critical: true, - Value: writeID, - } - - ephBuf, err := ephemeralPublicKey.MarshalBinary() - if err != nil { - return nil, Erret(err) - } - ephemeralKeyExt := pkix.Extension{ - Id: EphemeralKeyOID, - Critical: true, - Value: ephBuf, - } - - template := x509.Certificate{ - SerialNumber: serialNumber, - Subject: pkix.Name{ - CommonName: "Ephemeral read operation & Co", - }, - NotBefore: notBefore, - NotAfter: notAfter, - - KeyUsage: x509.KeyUsageKeyEncipherment, - BasicConstraintsValid: true, - IsCA: false, - } - - template.ExtraExtensions = append(template.ExtraExtensions, writeIdExt, ephemeralKeyExt) - - throwaway, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) - if err != nil { - return nil, Erret(err) - } - derBytes, err := x509.CreateCertificate(rand.Reader, &template, caCert, &throwaway.PublicKey, caPrivKey) - if err != nil { - return nil, Erret(err) - } - - cert, err := x509.ParseCertificate(derBytes) - if err != nil { - return nil, Erret(err) - } - - return cert, nil -} diff --git a/ocs/db.go b/ocs/db.go index 6a74597edd..517a390de0 100644 --- a/ocs/db.go +++ b/ocs/db.go @@ -19,14 +19,14 @@ var storageKey = []byte("storage") // storage is used to save all elements of the DKG. type storage struct { Element map[string]*storageElement - PolicyCreateOCS []Policy + PolicyCreateOCS []PolicyCreate sync.Mutex } type storageElement struct { - PolicyReencrypt Policy - PolicyReshare Policy + PolicyReencrypt PolicyReencrypt + PolicyReshare PolicyReshare Shared dkgprotocol.SharedSecret Polys pubPoly Roster onet.Roster diff --git a/ocs/demo/Makefile b/ocs/demo/Makefile new file mode 100644 index 0000000000..c527e69bf5 --- /dev/null +++ b/ocs/demo/Makefile @@ -0,0 +1,15 @@ +all: run_conodes run_main + +run_main: + go run main.go data/public.toml + +run_conodes: compile_conode stop_conodes + docker run -p 7770-7775:7770-7775 --rm -v$$(pwd)/data:/conode_data -e COTHORITY_ALLOW_INSECURE_ADMIN=true \ + --name conode_test c4dt/ocs:dev ./run_nodes.sh -n 3 -v 2 -c -d /conode_data & + sleep 5 + +compile_conode: + make -C ../../conode docker_dev + +stop_conodes: + docker rm -f conode_test || true diff --git a/ocs/demo/main.go b/ocs/demo/main.go index 318d3b5505..12744a570d 100644 --- a/ocs/demo/main.go +++ b/ocs/demo/main.go @@ -10,8 +10,6 @@ import ( "bytes" "os" - "go.dedis.ch/cothority/v3/ocs/certs" - "go.dedis.ch/cothority/v3" "go.dedis.ch/cothority/v3/byzcoin/bcadmin/lib" "go.dedis.ch/cothority/v3/ocs" @@ -20,7 +18,7 @@ import ( ) func main() { - if len(os.Args) != 2 { + if len(os.Args) < 2 { log.Fatal("Please give a roster.toml as first parameter") } roster, err := lib.ReadRoster(os.Args[1]) @@ -28,33 +26,47 @@ func main() { log.Info("1. Creating createOCS cert and setting OCS-create policy") cl := ocs.NewClient() - coPrivKey, coCert, err := certs.CreateCertCa() - log.ErrFatal(err) + caCreate1 := ocs.NewBCCA("Create OCS - 1") + caCreate2 := ocs.NewBCCA("Create OCS - 2") for _, si := range roster.List { - err = cl.AddPolicyCreateOCS(si, ocs.Policy{X509Cert: &ocs.PolicyX509Cert{ - CA: [][]byte{coCert.Raw}, + err = cl.AddPolicyCreateOCS(si, ocs.PolicyCreate{X509Cert: &ocs.PolicyX509Cert{ + CA: [][]byte{caCreate1.Certificate.Raw, caCreate2.Certificate.Raw}, + Threshold: 2, }}) log.ErrFatal(err) } - log.Info("2.a) Creating node cert") - nodePrivKey, nodeCert, err := certs.CreateCertNode(coCert, coPrivKey) - log.ErrFatal(err) - - px := ocs.Policy{ + log.Info("2.a) Creating new OCS") + caReenc1 := ocs.NewBCCA("Reencrypt - 1") + caReenc2 := ocs.NewBCCA("Reencrypt - 2") + pxReenc := ocs.PolicyReencrypt{ + X509Cert: &ocs.PolicyX509Cert{ + CA: [][]byte{caReenc1.Certificate.Raw, + caReenc2.Certificate.Raw}, + Threshold: 2, + }, + } + pxReshare := ocs.PolicyReshare{ X509Cert: &ocs.PolicyX509Cert{ - CA: [][]byte{nodeCert.Raw}, - Threshold: 1, + CA: [][]byte{caReenc1.Certificate.Raw, + caReenc2.Certificate.Raw}, + Threshold: 2, + }, + } + cert1 := caCreate1.CreateOCS(pxReenc.X509Cert, pxReshare.X509Cert, *roster).Certificate.Raw + cert2 := caCreate2.CreateOCS(pxReenc.X509Cert, pxReshare.X509Cert, *roster).Certificate.Raw + authCreate := ocs.AuthCreate{ + X509Cert: &ocs.AuthCreateX509Cert{ + Certificates: [][]byte{cert1, cert2}, }, } - log.Info("2.b) Creating new OCS") - oid, err := cl.CreateOCS(*roster, px, px) + ocsID, err := cl.CreateOCS(*roster, authCreate, pxReenc, pxReshare) log.ErrFatal(err) - log.Infof("New OCS created with ID: %x", oid) + log.Infof("New OCS created with ID: %x", ocsID) - log.Info("2.c) Get proofs of all nodes") - proof, err := cl.GetProofs(*roster, oid) + log.Info("2.b) Get proofs of all nodes") + proof, err := cl.GetProofs(*roster, ocsID) log.ErrFatal(err) log.ErrFatal(proof.Verify()) log.Info("Proof got verified successfully on nodes:") @@ -64,31 +76,35 @@ func main() { log.Info("3.a) Creating secret key and encrypting it with the OCS-key") secret := []byte("ocs for everybody") - X, err := oid.X() + X, err := ocsID.X() log.ErrFatal(err) - U, C, err := certs.EncodeKey(cothority.Suite, X, secret) + U, C, err := ocs.EncodeKey(cothority.Suite, X, secret) log.ErrFatal(err) - log.Info("3.b) Creating certificate for the re-encryption") - kp := key.NewKeyPair(cothority.Suite) - wid, err := certs.NewWriteID(X, U) + log.Info("3.b) Creating 2 certificates for the re-encryption") + ephemeralKeyPair := key.NewKeyPair(cothority.Suite) + wid, err := ocs.NewWriteID(X, U) log.ErrFatal(err) - reencryptCert, err := certs.CreateCertReencrypt(nodeCert, nodePrivKey, wid, kp.Public) + reencryptCert1, err := ocs.CreateCertReencrypt(caReenc1.Certificate, caReenc1.Private, + wid, ephemeralKeyPair.Public) log.ErrFatal(err) - auth := ocs.AuthReencrypt{ - Ephemeral: kp.Public, + reencryptCert2, err := ocs.CreateCertReencrypt(caReenc2.Certificate, caReenc2.Private, + wid, ephemeralKeyPair.Public) + log.ErrFatal(err) + + log.Info("4. Asking OCS to re-encrypt the secret to an ephemeral key") + authRe := ocs.AuthReencrypt{ + Ephemeral: ephemeralKeyPair.Public, X509Cert: &ocs.AuthReencryptX509Cert{ U: U, - Certificates: [][]byte{reencryptCert.Raw}, + Certificates: [][]byte{reencryptCert1.Raw, reencryptCert2.Raw}, }, } - - log.Info("4. Asking OCS to re-encrypt the secret to an ephemeral key") - XhatEnc, err := cl.Reencrypt(*roster, oid, auth) + XhatEnc, err := cl.Reencrypt(*roster, ocsID, authRe) log.ErrFatal(err) log.Info("5. Decrypt the symmetric key") - secretRec, err := certs.DecodeKey(cothority.Suite, X, C, XhatEnc, kp.Private) + secretRec, err := ocs.DecodeKey(cothority.Suite, X, C, XhatEnc, ephemeralKeyPair.Private) log.ErrFatal(err) if bytes.Compare(secret, secretRec) != 0 { log.Fatal("Recovered secret is not the same") diff --git a/ocs/helper.go b/ocs/helper.go new file mode 100644 index 0000000000..bf43847a1a --- /dev/null +++ b/ocs/helper.go @@ -0,0 +1,236 @@ +package ocs + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "crypto/x509/pkix" + "errors" + "fmt" + "math/big" + "runtime" + "strings" + "time" + + "go.dedis.ch/onet/v3" + "go.dedis.ch/protobuf" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/suites" + "go.dedis.ch/onet/v3/log" +) + +// EncodeKey can be used by the writer to an onchain-secret skipchain +// to encode his symmetric key under the collective public key created +// by the DKG. +// As this method uses `Pick` to encode the key, depending on the key-length +// more than one point is needed to encode the data. +// +// Input: +// - suite - the cryptographic suite to use +// - X - the aggregate public key of the DKG +// - key - the symmetric key for the document +// +// Output: +// - U - the schnorr commit +// - C - encrypted key +func EncodeKey(suite suites.Suite, X kyber.Point, key []byte) (U kyber.Point, C kyber.Point, err error) { + if len(key) > suite.Point().EmbedLen() { + return nil, nil, errors.New("got more data than can fit into one point") + } + r := suite.Scalar().Pick(suite.RandomStream()) + C = suite.Point().Mul(r, X) + log.Lvl3("C:", C.String()) + U = suite.Point().Mul(r, nil) + log.Lvl3("U is:", U.String()) + + kp := suite.Point().Embed(key, suite.RandomStream()) + log.Lvl3("Keypoint:", kp.String()) + log.Lvl3("X:", X.String()) + C.Add(C, kp) + return +} + +// DecodeKey can be used by the reader of an onchain-secret to convert the +// re-encrypted secret back to a symmetric key that can be used later to +// decode the document. +// +// Input: +// - suite - the cryptographic suite to use +// - X - the aggregate public key of the DKG +// - C - the encrypted key +// - XhatEnc - the re-encrypted schnorr-commit +// - xc - the private key of the reader +// +// Output: +// - key - the re-assembled key +// - err - an eventual error when trying to recover the data from the points +func DecodeKey(suite kyber.Group, X kyber.Point, C kyber.Point, XhatEnc kyber.Point, + xc kyber.Scalar) (key []byte, err error) { + log.Lvl3("xc:", xc) + xcInv := suite.Scalar().Neg(xc) + log.Lvl3("xcInv:", xcInv) + sum := suite.Scalar().Add(xc, xcInv) + log.Lvl3("xc + xcInv:", sum, "::", xc) + log.Lvl3("X:", X) + XhatDec := suite.Point().Mul(xcInv, X) + log.Lvl3("XhatDec:", XhatDec) + log.Lvl3("XhatEnc:", XhatEnc) + Xhat := suite.Point().Add(XhatEnc, XhatDec) + log.Lvl3("Xhat:", Xhat) + XhatInv := suite.Point().Neg(Xhat) + log.Lvl3("XhatInv:", XhatInv) + + // Decrypt C to keyPointHat + log.Lvl3("C:", C) + keyPointHat := suite.Point().Add(C, XhatInv) + log.Lvl3("keyPointHat:", keyPointHat) + key, err = keyPointHat.Data() + if err != nil { + return nil, Erret(err) + } + log.Lvl3("key:", key) + return +} + +func Erret(err error) error { + if err == nil { + return nil + } + pc, _, line, _ := runtime.Caller(1) + errStr := err.Error() + if strings.HasPrefix(errStr, "Erret") { + errStr = "\n\t" + errStr + } + return fmt.Errorf("Erret at %s: %d -> %s", runtime.FuncForPC(pc).Name(), line, errStr) +} + +// Helper functions to create x509-certificates. +// +// CertNode - can be given as a CA for Reencryption and Resharing +// +-> CertReencrypt - indicates who is allowed to reencrypt and gives the ephemeral key + +// BCCert is used as a structure in testing - this is not secure enough to be used in production. +type BCCert struct { + Private *ecdsa.PrivateKey + Certificate *x509.Certificate +} + +// NewBCCert is the general method to create a certificate for testing. +func NewBCCert(cn string, dur time.Duration, kus x509.KeyUsage, isCA bool, + eext []pkix.Extension, root *x509.Certificate, rootPriv *ecdsa.PrivateKey) BCCert { + notBefore := time.Now() + notAfter := notBefore.Add(dur) + serialNumber := big.NewInt(int64(1)) + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + CommonName: cn, + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: kus, + BasicConstraintsValid: true, + MaxPathLen: 2, + IsCA: isCA, + } + if eext != nil { + template.ExtraExtensions = eext + } + bcc := BCCert{} + var err error + bcc.Private, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) + log.ErrFatal(err) + if root == nil { + root = &template + rootPriv = bcc.Private + } + derBytes, err := x509.CreateCertificate(rand.Reader, &template, root, &bcc.Private.PublicKey, rootPriv) + log.ErrFatal(err) + + bcc.Certificate, err = x509.ParseCertificate(derBytes) + log.ErrFatal(err) + return bcc +} + +// CADur is the duration for a CA - here artificially restricted to 24 hours, because it is for testing only. +var CADur = 24 * time.Hour + +// NewBCCA creates a CA cert. +func NewBCCA(cn string) BCCert { + return NewBCCert(cn, CADur, x509.KeyUsageCertSign|x509.KeyUsageDataEncipherment, true, + nil, nil, nil) +} + +// CreateSubCA creates a CA that is signed by the CA of the given bcc. +func (bcc BCCert) CreateSubCA(cn string) BCCert { + return NewBCCert(cn, CADur, x509.KeyUsageCertSign|x509.KeyUsageDataEncipherment, true, + nil, bcc.Certificate, bcc.Private) +} + +// Sign is a general signing method that creates a new certificate, which is not a CA. +func (bcc BCCert) Sign(cn string, eext []pkix.Extension) BCCert { + return NewBCCert(cn, time.Hour, x509.KeyUsageKeyEncipherment, false, eext, bcc.Certificate, bcc.Private) +} + +// Reencrypt is a specific reencryption certificate created with extrafields that are used by Calypso. +func (bcc BCCert) Reencrypt(writeID []byte, ephemeralPublicKey kyber.Point) BCCert { + writeIdExt := pkix.Extension{ + Id: OIDWriteId, + Critical: true, + Value: writeID, + } + + ephemeralKeyExt := pkix.Extension{ + Id: OIDEphemeralKey, + Critical: true, + } + var err error + ephemeralKeyExt.Value, err = ephemeralPublicKey.MarshalBinary() + log.ErrFatal(err) + + return bcc.Sign("reencryt", []pkix.Extension{writeIdExt, ephemeralKeyExt}) +} + +// CreateOCS returns a certificate that can be used to authenticate for OCS creation. +func (bcc BCCert) CreateOCS(policyReencrypt, policyReshare *PolicyX509Cert, roster onet.Roster) BCCert { + pReencBuf, err := protobuf.Encode(policyReencrypt) + log.ErrFatal(err) + pReshareBuf, err := protobuf.Encode(policyReshare) + log.ErrFatal(err) + rosterBuf, err := protobuf.Encode(&roster) + log.ErrFatal(err) + return bcc.Sign("createOCS", []pkix.Extension{ + { + Id: OIDPolicyReencrypt, + Critical: true, + Value: pReencBuf, + }, + { + Id: OIDPolicyReshare, + Critical: true, + Value: pReshareBuf, + }, + { + Id: OIDRoster, + Critical: true, + Value: rosterBuf, + }, + }) +} + +// CreateCertCa is used for tests and returns a new private key, as well as a CA certificate. +func CreateCertCa() (caPrivKey *ecdsa.PrivateKey, cert *x509.Certificate, err error) { + bcc := NewBCCA("ByzGen signer org1") + return bcc.Private, bcc.Certificate, nil +} + +// CreateCertReencrypt is used for tests and can create a certificate for a reencryption request. +func CreateCertReencrypt(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, + writeID []byte, ephemeralPublicKey kyber.Point) (*x509.Certificate, error) { + bcc := BCCert{Certificate: caCert, Private: caPrivKey}.Reencrypt(writeID, ephemeralPublicKey) + return bcc.Certificate, nil +} diff --git a/ocs/proto.go b/ocs/proto.go index ea787f5e85..3ce8f31856 100644 --- a/ocs/proto.go +++ b/ocs/proto.go @@ -30,7 +30,7 @@ import ( // AddPolicyCreateOCS is sent by a local admin to add a rule to define who is // authorized to create a new OCS. type AddPolicyCreateOCS struct { - Create Policy + Create PolicyCreate } // AddPolicyCreateOCSReply is an empty reply if the policy has been successfully @@ -47,8 +47,9 @@ type AddPolicyCreateOCSReply struct { // the policies will differ for this new backend. type CreateOCS struct { Roster onet.Roster - PolicyReencrypt Policy - PolicyReshare Policy + Auth AuthCreate + PolicyReencrypt PolicyReencrypt + PolicyReshare PolicyReshare } // CreateOCSReply is the reply sent by the conode if the OCS has been @@ -87,7 +88,6 @@ type Reencrypt struct { type ReencryptReply struct { X kyber.Point XhatEnc kyber.Point - C kyber.Point } // Reshare is called to ask OCS to change the roster. It needs a valid @@ -112,9 +112,23 @@ type ReshareReply struct { // Common structures // *** -// Policy holds all possible authentication structures. When using it to call -// Authorise, only one of the fields must be non-nil. -type Policy struct { +// PolicyCreate holds all possible policy structures for creation of a new OCS. +// Only one of the fields must be non-nil, else the policy is invalid. +type PolicyCreate struct { + ByzCoin *PolicyByzCoin + X509Cert *PolicyX509Cert +} + +// PolicyReencrypt holds all possible policy structures for creation of a new OCS. +// Only one of the fields must be non-nil, else the policy is invalid. +type PolicyReencrypt struct { + ByzCoin *PolicyByzCoin + X509Cert *PolicyX509Cert +} + +// PolicyReshare holds all possible policy structures for creation of a new OCS. +// Only one of the fields must be non-nil, else the policy is invalid. +type PolicyReshare struct { ByzCoin *PolicyByzCoin X509Cert *PolicyX509Cert } @@ -142,19 +156,21 @@ type PolicyX509Cert struct { // AuthCreate prooves that the caller has the right to create a new OCS // instance. type AuthCreate struct { - ByzCoin AuthCreateByzcoin - X509Cert AuthCreateX509Cert + ByzCoin *AuthCreateByzCoin + X509Cert *AuthCreateX509Cert } -// AuthCreateByzcoin must give the ByzcoinID and the proof to the LTSInstance +// AuthCreateByzCoin must give the ByzcoinID and the proof to the LTSInstance // for the creation of a new OCS. -type AuthCreateByzcoin struct { +type AuthCreateByzCoin struct { ByzcoinID skipchain.SkipBlockID LTSInstance byzcoin.Proof } -// AuthCreateX509Cert must give a threshold number of certificates to proof that -// the caller has the right to create a new OCS. +// AuthCreateX509Cert must give one or more certificates rooted in the CreatePolicy certificate +// to proof that the caller has the right to create a new OCS. The number of certificates +// needed is defined by the Threshold field of the CreatePolicy. Each certificate must come +// from another CA. type AuthCreateX509Cert struct { Certificates [][]byte } @@ -220,7 +236,7 @@ type AuthReshareX509Cert struct { type OCSProof struct { OcsID OCSID Roster onet.Roster - PolicyReencrypt Policy - PolicyReshare Policy + PolicyReencrypt PolicyReencrypt + PolicyReshare PolicyReshare Signatures [][]byte } diff --git a/ocs/service.go b/ocs/service.go index dffa434ea6..a49c872a78 100644 --- a/ocs/service.go +++ b/ocs/service.go @@ -12,8 +12,6 @@ import ( "os" "time" - "go.dedis.ch/cothority/v3/ocs/certs" - "go.dedis.ch/kyber/v3/sign/schnorr" "go.dedis.ch/kyber/v3/suites" @@ -103,29 +101,35 @@ func (s *Service) AddPolicyCreateOCS(req *AddPolicyCreateOCS) (reply *AddPolicyC // participate in the DKG. Every node will store its private key and wait for // decryption requests. func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { - if err = req.verify(); err != nil { - return nil, certs.Erret(err) + s.storage.Lock() + policies := s.storage.PolicyCreateOCS + s.storage.Unlock() + if err = req.verifyAuth(policies); err != nil { + return nil, Erret(err) + } + if len(req.Roster.List) <= 1 { + return nil, errors.New("need at least 2 nodes for DKG") } tree := req.Roster.GenerateNaryTreeWithRoot(len(req.Roster.List), s.ServerIdentity()) cfgBuf, err := protobuf.Encode(req) if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } pi, err := s.CreateProtocol(dkgprotocol.Name, tree) if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } setupDKG := pi.(*dkgprotocol.Setup) setupDKG.Wait = true err = setupDKG.SetConfig(&onet.GenericConfig{Data: cfgBuf}) if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } setupDKG.KeyPair = s.getKeyPair() if err := pi.Start(); err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } log.Lvl3("Started DKG-protocol - waiting for done", len(req.Roster.List)) @@ -134,18 +138,18 @@ func (s *Service) CreateOCS(req *CreateOCS) (reply *CreateOCSReply, err error) { case <-setupDKG.Finished: shared, dks, err := setupDKG.SharedSecret() if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } ocsID, err := NewOCSID(shared.X) if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } reply = &CreateOCSReply{ OcsID: ocsID, } oid, err = shared.X.MarshalBinary() if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } s.storage.Lock() s.storage.Element[string(oid)] = &storageElement{ @@ -186,11 +190,11 @@ func (s *Service) GetProof(req *GetProof) (reply *GetProofReply, err error) { } msg, err := reply.Proof.Message() if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } sig, err := schnorr.Sign(cothority.Suite, s.ServerIdentity().ServicePrivate(ServiceName), msg) if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } reply.Proof.Signatures = [][]byte{sig} return @@ -223,23 +227,23 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { tree := es.Roster.GenerateNaryTreeWithRoot(nodes, s.ServerIdentity()) pi, err := s.CreateProtocol(NameOCS, tree) if err != nil { - return certs.Erret(err) + return Erret(err) } ocsProto = pi.(*OCS) ocsProto.U, err = dkr.Auth.U() if err != nil { - return certs.Erret(err) + return Erret(err) } X, err := dkr.OcsID.X() if err != nil { - return certs.Erret(err) + return Erret(err) } - if err = dkr.Auth.verify(es.PolicyReencrypt, X, ocsProto.U); err != nil { - return certs.Erret(err) + if err = es.PolicyReencrypt.verify(dkr.Auth, X, ocsProto.U); err != nil { + return Erret(err) } ocsProto.Xc, err = dkr.Auth.Xc() if err != nil { - return certs.Erret(err) + return Erret(err) } log.Lvlf2("%v Public key is: %s", s.ServerIdentity(), ocsProto.Xc) ocsProto.VerificationData, err = protobuf.Encode(&dkr.Auth) @@ -269,11 +273,11 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { log.Lvl3("Starting reencryption protocol", ocsProto.TreeNodeInstance.TokenID()) err = ocsProto.SetConfig(&onet.GenericConfig{Data: dkr.OcsID}) if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } err = ocsProto.Start() if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } if !<-ocsProto.Reencrypted { return nil, errors.New("reencryption got refused") @@ -282,10 +286,10 @@ func (s *Service) Reencrypt(dkr *Reencrypt) (reply *ReencryptReply, err error) { reply.XhatEnc, err = share.RecoverCommit(cothority.Suite, ocsProto.Uis, threshold, nodes) if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } log.Lvl3("Successfully reencrypted the key") return @@ -416,7 +420,9 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi if err := protobuf.DecodeWithConstructors(conf.Data, &cfg, network.DefaultConstructors(cothority.Suite)); err != nil { return nil, err } - if err := cfg.verify(); err != nil { + s.storage.Lock() + defer s.storage.Unlock() + if err := cfg.verifyAuth(s.storage.PolicyCreateOCS); err != nil { return nil, err } @@ -464,7 +470,15 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi if err := protobuf.DecodeWithConstructors(conf.Data, &cfg, network.DefaultConstructors(cothority.Suite)); err != nil { return nil, err } - if err := cfg.verify(); err != nil { + s.storage.Lock() + id := string(cfg.OcsID) + es, found := s.storage.Element[id] + s.storage.Unlock() + if !found { + // TODO: we might not have this yet - so probably we need to put the old roster in cfg, too. + return nil, errors.New("this OCSID is not known here") + } + if err := es.PolicyReshare.verify(cfg.Auth, cfg.NewRoster); err != nil { return nil, err } @@ -476,13 +490,6 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi setupDKG := pi.(*dkgprotocol.Setup) setupDKG.KeyPair = s.getKeyPair() - s.storage.Lock() - id := string(cfg.OcsID) - es, found := s.storage.Element[id] - if !found { - // TODO: we might not have this yet - so probably we need to put the old roster in cfg, too. - return nil, errors.New("this OCSID is not known here") - } oldNodes := es.Roster.Publics() n := len(tn.Roster().List) c := &dkg.Config{ @@ -501,7 +508,6 @@ func (s *Service) NewProtocol(tn *onet.TreeNodeInstance, conf *onet.GenericConfi // TODO: add commits here //c.PublicCoeffs = cfg.Commits } - s.storage.Unlock() setupDKG.NewDKG = func() (*dkg.DistKeyGenerator, error) { d, err := dkg.NewDistKeyHandler(c) @@ -588,7 +594,6 @@ func pointInList(p1 kyber.Point, l []kyber.Point) bool { // verifyReencryption checks that the read and the write instances match. func (s *Service) verifyReencryption(rc *MessageReencrypt) bool { - // TODO: check the correct authentication err := func() error { if rc.VerificationData == nil { return errors.New("need verification data") @@ -596,11 +601,11 @@ func (s *Service) verifyReencryption(rc *MessageReencrypt) bool { var arc AuthReencrypt err := protobuf.DecodeWithConstructors(*rc.VerificationData, &arc, network.DefaultConstructors(cothority.Suite)) if err != nil { - return certs.Erret(err) + return Erret(err) } Xc, err := arc.Xc() if err != nil { - return certs.Erret(err) + return Erret(err) } if !Xc.Equal(rc.Xc) { return errors.New("xcs don't match up") diff --git a/ocs/service_test.go b/ocs/service_test.go index 4327c3530e..c5f4fd6587 100644 --- a/ocs/service_test.go +++ b/ocs/service_test.go @@ -1,17 +1,15 @@ package ocs import ( + "fmt" "testing" - "go.dedis.ch/kyber/v3/util/key" - - "go.dedis.ch/onet/v3/log" - - "go.dedis.ch/cothority/v3" - "github.com/stretchr/testify/require" - + "go.dedis.ch/cothority/v3" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/util/key" "go.dedis.ch/onet/v3" + "go.dedis.ch/onet/v3/log" ) func TestMain(m *testing.M) { @@ -25,34 +23,33 @@ func TestService_CreateOCS(t *testing.T) { nbrNodes := 2 servers, roster, _ := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) + cc := newCaCerts(2, 2, 2) + cc.addPolicy(servers) + // Test setting up a new OCS with a valid X509 s1 := servers[0].Service(ServiceName).(*Service) - px := Policy{ - X509Cert: &PolicyX509Cert{}, - } + log.Lvl1("Start with insufficient number of authentications") co := &CreateOCS{ Roster: *roster, - PolicyReencrypt: px, - PolicyReshare: px, + Auth: cc.authCreate(1, *roster), + PolicyReencrypt: cc.policyReencrypt, + PolicyReshare: cc.policyReshare, } + _, err := servers[0].Service(ServiceName).(*Service).CreateOCS(co) + + log.Lvl1("Continue with copied authentication") + ac := cc.authCreate(1, *roster) + co.Auth.X509Cert.Certificates = append(co.Auth.X509Cert.Certificates, ac.X509Cert.Certificates[0]) cor, err := s1.CreateOCS(co) + require.Error(t, err) + + log.Lvl1("Correct authentication") + co.Auth = cc.authCreate(2, *roster) + cor, err = s1.CreateOCS(co) require.NoError(t, err) require.NotNil(t, cor) require.NotNil(t, cor.OcsID) - - // Do the same with an invalid X509 - px.X509Cert.CA = nil - co = &CreateOCS{ - Roster: *roster, - PolicyReencrypt: px, - PolicyReshare: px, - } - cor, err = s1.CreateOCS(co) - // TODO: enable test of failing creation - //require.Error(t, err) - - // TODO: test setting up a new OCS with ByzCoin } // Encrypt some data and then re-encrypt it to another public key. @@ -62,28 +59,12 @@ func TestService_Reencrypt(t *testing.T) { nbrNodes := 5 servers, roster, _ := local.GenBigTree(nbrNodes, nbrNodes, nbrNodes, true) + cc := newCaCerts(1, 2, 2) + cor := cc.createOCS(servers, *roster) + // Test setting up a new OCS with a valid X509 s1 := servers[0].Service(ServiceName).(*Service) - caPrivKey, caCert, err := CreateCertCa() - require.NoError(t, err) - caPrivKeyAttack, caCertAttack, err := CreateCertCa() - require.NoError(t, err) - - px := Policy{ - X509Cert: &PolicyX509Cert{ - CA: [][]byte{caCert.Raw}, - Threshold: 1, - }, - } - co := &CreateOCS{ - Roster: *roster, - PolicyReencrypt: px, - PolicyReshare: px, - } - cor, err := s1.CreateOCS(co) - require.NoError(t, err) - secret := []byte("ocs for all") X, err := cor.OcsID.X() require.NoError(t, err) @@ -93,24 +74,20 @@ func TestService_Reencrypt(t *testing.T) { kp := key.NewKeyPair(cothority.Suite) wid, err := NewWriteID(X, U) require.NoError(t, err) - reencryptCert, err := CreateCertReencrypt(caCertAttack, caPrivKeyAttack, wid, kp.Public) - require.NoError(t, err) req := &Reencrypt{ OcsID: cor.OcsID, Auth: AuthReencrypt{ Ephemeral: kp.Public, X509Cert: &AuthReencryptX509Cert{ U: U, - Certificates: [][]byte{reencryptCert.Raw}, + Certificates: cc.authReencrypt(1, wid, kp.Public), }, }, } rr, err := s1.Reencrypt(req) require.Error(t, err) - reencryptCert, err = CreateCertReencrypt(caCert, caPrivKey, wid, kp.Public) - require.NoError(t, err) - req.Auth.X509Cert.Certificates = [][]byte{reencryptCert.Raw} + req.Auth.X509Cert.Certificates = cc.authReencrypt(2, wid, kp.Public) rr, err = s1.Reencrypt(req) require.NoError(t, err) @@ -119,3 +96,84 @@ func TestService_Reencrypt(t *testing.T) { require.NoError(t, err) require.Equal(t, secret, secretRec) } + +type caCerts struct { + caCreate []BCCert + caReencrypt []BCCert + caReshare []BCCert + policyCreate PolicyCreate + policyReencrypt PolicyReencrypt + policyReshare PolicyReshare +} + +func newCaCerts(nbrCr, nbrReenc, nbrReshare int) caCerts { + cc := caCerts{} + var cas [][]byte + for i := 0; i < nbrCr; i++ { + ca := NewBCCA(fmt.Sprintf("CA-Create %d", i)) + cc.caCreate = append(cc.caCreate, ca) + cas = append(cas, ca.Certificate.Raw) + } + cc.policyCreate.X509Cert = &PolicyX509Cert{CA: cas, Threshold: nbrCr} + + cas = [][]byte{} + for i := 0; i < nbrReenc; i++ { + ca := NewBCCA(fmt.Sprintf("CA-Reencrypt %d", i)) + cc.caReencrypt = append(cc.caReencrypt, ca) + cas = append(cas, ca.Certificate.Raw) + } + cc.policyReencrypt.X509Cert = &PolicyX509Cert{CA: cas, Threshold: nbrReenc} + + cas = [][]byte{} + for i := 0; i < nbrReshare; i++ { + ca := NewBCCA(fmt.Sprintf("CA-Reshare %d", i)) + cc.caReshare = append(cc.caReshare, ca) + cas = append(cas, ca.Certificate.Raw) + } + cc.policyReshare.X509Cert = &PolicyX509Cert{CA: cas, Threshold: nbrReshare} + return cc +} + +func (cc caCerts) addPolicy(servers []*onet.Server) { + for _, s := range servers { + _, err := s.Service(ServiceName).(*Service).AddPolicyCreateOCS(&AddPolicyCreateOCS{Create: cc.policyCreate}) + log.ErrFatal(err) + } +} + +func (cc caCerts) createOCS(servers []*onet.Server, roster onet.Roster) *CreateOCSReply { + cc.addPolicy(servers) + co := &CreateOCS{ + Roster: roster, + Auth: cc.authCreate(1, roster), + PolicyReencrypt: cc.policyReencrypt, + PolicyReshare: cc.policyReshare, + } + cor, err := servers[0].Service(ServiceName).(*Service).CreateOCS(co) + log.ErrFatal(err) + return cor +} + +func (cc caCerts) authCreate(nbr int, r onet.Roster) (ac AuthCreate) { + if nbr > len(cc.caCreate) { + log.Fatal("asked for too many certificates") + } + acx := &AuthCreateX509Cert{} + for _, ca := range cc.caCreate[0:nbr] { + auth := ca.CreateOCS(cc.policyReencrypt.X509Cert, cc.policyReshare.X509Cert, r) + acx.Certificates = append(acx.Certificates, auth.Certificate.Raw) + } + ac.X509Cert = acx + return +} + +func (cc caCerts) authReencrypt(nbr int, wrID []byte, ephKey kyber.Point) (certs [][]byte) { + if nbr > len(cc.caReencrypt) { + log.Fatal("asked for too many certificates") + } + for _, ca := range cc.caReencrypt[0:nbr] { + auth := ca.Reencrypt(wrID, ephKey) + certs = append(certs, auth.Certificate.Raw) + } + return +} diff --git a/ocs/struct.go b/ocs/struct.go index e288f111df..25a94aa96b 100644 --- a/ocs/struct.go +++ b/ocs/struct.go @@ -2,42 +2,27 @@ package ocs import ( "crypto/sha256" - "crypto/x509" "errors" - "go.dedis.ch/cothority/v3/ocs/certs" - "go.dedis.ch/cothority/v3" "go.dedis.ch/kyber/v3/sign/schnorr" "go.dedis.ch/protobuf" "go.dedis.ch/kyber/v3" - - "go.dedis.ch/onet/v3" ) -func (ocs CreateOCS) verify() error { - if err := ocs.PolicyReencrypt.verify(ocs.Roster); err != nil { - return err - } - if err := ocs.PolicyReshare.verify(ocs.Roster); err != nil { - return err - } - return nil -} - func (op OCSProof) Verify() error { if len(op.Signatures) != len(op.Roster.List) { return errors.New("length of signatures is not equal to roster list length") } msg, err := op.Message() if err != nil { - return certs.Erret(err) + return Erret(err) } for i, si := range op.Roster.List { err := schnorr.Verify(cothority.Suite, si.ServicePublic(ServiceName), msg, op.Signatures[i]) if err != nil { - return certs.Erret(err) + return Erret(err) } } return nil @@ -53,54 +38,15 @@ func (op OCSProof) Message() ([]byte, error) { } buf, err := protobuf.Encode(&coc) if err != nil { - return nil, certs.Erret(err) + return nil, Erret(err) } hash.Write(buf) return hash.Sum(nil), nil } -func (re Reshare) verify() error { - return errors.New("not yet implemented") -} - -func (p Policy) verify(r onet.Roster) error { - if p.X509Cert != nil { - return p.X509Cert.verify(r) - } - if p.ByzCoin != nil { - return p.ByzCoin.verify(r) - } - return errors.New("need to have a policy for X509 or ByzCoin") -} - -func (px PolicyX509Cert) verify(r onet.Roster) error { - // TODO: decide how to make sure the policy fits the reencryption / resharing - return nil -} - -func (px PolicyByzCoin) verify(r onet.Roster) error { - return certs.Erret(errors.New("not yet implemented")) -} - -func (ar AuthReencrypt) verify(p Policy, X, U kyber.Point) error { - if ar.X509Cert == nil || p.X509Cert == nil { - return errors.New("currently only checking X509 policies") - } - root, err := x509.ParseCertificate(p.X509Cert.CA[0]) - if err != nil { - return certs.Erret(err) - } - auth, err := x509.ParseCertificate(ar.X509Cert.Certificates[0]) - if err != nil { - return certs.Erret(err) - } - - return certs.Erret(certs.Verify(root, auth, X, U)) -} - func (ar AuthReencrypt) Xc() (kyber.Point, error) { if ar.X509Cert != nil { - return certs.GetPointFromCert(ar.X509Cert.Certificates[0], certs.EphemeralKeyOID) + return GetPointFromCert(ar.X509Cert.Certificates[0], OIDEphemeralKey) } if ar.ByzCoin != nil { return nil, errors.New("can't get ephemeral key from ByzCoin yet") @@ -124,6 +70,6 @@ func NewOCSID(X kyber.Point) (OCSID, error) { func (ocs OCSID) X() (kyber.Point, error) { X := cothority.Suite.Point() - err := certs.Erret(X.UnmarshalBinary(ocs)) + err := Erret(X.UnmarshalBinary(ocs)) return X, err } diff --git a/ocs/struct_test.go b/ocs/struct_test.go new file mode 100644 index 0000000000..b510ee2ecb --- /dev/null +++ b/ocs/struct_test.go @@ -0,0 +1,36 @@ +package ocs + +import ( + "testing" + + "go.dedis.ch/cothority/v3" + "go.dedis.ch/onet/v3" + + "github.com/stretchr/testify/require" +) + +// TestStruct_MultiSign makes sure that with 3 CAs and a threshold of 2, verification outputs: +// - OK for 2 certificates signed by any two different CAs +// - OK for 3 certificates signed by any two different CAs +// - FALSE for 2 certificates signed by the same CA +// - FALSE for 1 certificate +func TestStruct_MultiSign(t *testing.T) { + l := onet.NewLocalTest(cothority.Suite) + _, r, _ := l.GenTree(2, true) + defer l.CloseAll() + cc := newCaCerts(3, 3, 3) + cc.policyCreate.X509Cert.Threshold = 2 + + auth := cc.authCreate(1, *r) + require.Error(t, cc.policyCreate.verify(auth, cc.policyReencrypt, cc.policyReshare, *r)) + auth2 := cc.authCreate(1, *r) + auth.X509Cert.Certificates = append(auth.X509Cert.Certificates, auth2.X509Cert.Certificates[0]) + require.Error(t, cc.policyCreate.verify(auth, cc.policyReencrypt, cc.policyReshare, *r)) + + auth = cc.authCreate(3, *r) + require.NoError(t, cc.policyCreate.verify(auth, cc.policyReencrypt, cc.policyReshare, *r)) + auth.X509Cert.Certificates = auth.X509Cert.Certificates[1:] + require.NoError(t, cc.policyCreate.verify(auth, cc.policyReencrypt, cc.policyReshare, *r)) + auth.X509Cert.Certificates = append(auth.X509Cert.Certificates, auth.X509Cert.Certificates[0]) + require.NoError(t, cc.policyCreate.verify(auth, cc.policyReencrypt, cc.policyReshare, *r)) +} From 3f14a2ea850478bf3962b64abcbffa2b5dfc9134 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Thu, 9 May 2019 16:30:09 +0200 Subject: [PATCH 18/21] printing scalars and points --- go.mod | 1 + ocs/demo/main.go | 64 +- ocs/edwards25519/LICENSE | 29 + ocs/edwards25519/allowvt_test.go | 20 + ocs/edwards25519/const.go | 1446 +++++++++++++++++ ocs/edwards25519/curve.go | 60 + ocs/edwards25519/curve_test.go | 31 + ocs/edwards25519/fe.go | 986 ++++++++++++ ocs/edwards25519/ge.go | 489 ++++++ ocs/edwards25519/ge_mult_vartime.go | 71 + ocs/edwards25519/marshal.go | 83 + ocs/edwards25519/point.go | 252 +++ ocs/edwards25519/point_test.go | 13 + ocs/edwards25519/point_vartime.go | 9 + ocs/edwards25519/scalar.go | 2231 +++++++++++++++++++++++++++ ocs/edwards25519/scalar_test.go | 459 ++++++ ocs/edwards25519/suite.go | 70 + 17 files changed, 6313 insertions(+), 1 deletion(-) create mode 100644 ocs/edwards25519/LICENSE create mode 100644 ocs/edwards25519/allowvt_test.go create mode 100644 ocs/edwards25519/const.go create mode 100644 ocs/edwards25519/curve.go create mode 100644 ocs/edwards25519/curve_test.go create mode 100644 ocs/edwards25519/fe.go create mode 100644 ocs/edwards25519/ge.go create mode 100644 ocs/edwards25519/ge_mult_vartime.go create mode 100644 ocs/edwards25519/marshal.go create mode 100644 ocs/edwards25519/point.go create mode 100644 ocs/edwards25519/point_test.go create mode 100644 ocs/edwards25519/point_vartime.go create mode 100644 ocs/edwards25519/scalar.go create mode 100644 ocs/edwards25519/scalar_test.go create mode 100644 ocs/edwards25519/suite.go diff --git a/go.mod b/go.mod index c5b91663f2..2beeb1ce6f 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/qantik/qrgo v0.0.0-20160917134849-0c6b902c59f6 github.com/satori/go.uuid v1.2.0 github.com/stretchr/testify v1.3.0 + go.dedis.ch/fixbuf v1.0.3 go.dedis.ch/kyber/v3 v3.0.2 go.dedis.ch/onet/v3 v3.0.5 go.dedis.ch/protobuf v1.0.6 diff --git a/ocs/demo/main.go b/ocs/demo/main.go index 12744a570d..c314c79fc6 100644 --- a/ocs/demo/main.go +++ b/ocs/demo/main.go @@ -8,7 +8,14 @@ package main import ( "bytes" + "fmt" + "math/big" "os" + "strings" + + "go.dedis.ch/cothority/v3/ocs/edwards25519" + + "go.dedis.ch/kyber/v3" "go.dedis.ch/cothority/v3" "go.dedis.ch/cothority/v3/byzcoin/bcadmin/lib" @@ -17,9 +24,64 @@ import ( "go.dedis.ch/onet/v3/log" ) +func bigEndianToDecimal(buf []byte) *big.Int { + bi := &big.Int{} + bi.SetBytes(buf) + return bi +} + +func LEBytesToDecimal(buf []byte) *big.Int { + if len(buf)%2 != 0 { + log.Fatal("can only convert even length slices") + } + for i := 0; i < len(buf)/2; i++ { + buf[i], buf[len(buf)-i-1] = buf[len(buf)-i-1], buf[i] + } + return bigEndianToDecimal(buf) +} + +func printScalar(msg string, s kyber.Scalar) { + buf, err := s.MarshalBinary() + log.ErrFatal(err) + var str []string + str = append(str, fmt.Sprint("Representation of a scalar:")) + str = append(str, fmt.Sprintf("\tLittle-endian: %x", buf)) + str = append(str, fmt.Sprintf("\tDecimal: %s", LEBytesToDecimal(buf).String())) + log.Info(msg, strings.Join(str, "\n")) +} + +func printPoint(msg string, p kyber.Point) { + ped := p.(*edwards25519.Point) + var str []string + str = append(str, fmt.Sprint("Representations of a point:")) + str = append(str, fmt.Sprintf("\tCompressed: %s", ped.String())) + str = append(str, fmt.Sprintf("\tLittle-endian X / Y:\n\t\tX: %x\n\t\tY: %x", ped.X_LE(), ped.Y_LE())) + str = append(str, fmt.Sprintf("\tDecimal X / Y:\n\t\tX: %s\n\t\tY: %s", + LEBytesToDecimal(ped.X_LE()).String(), + LEBytesToDecimal(ped.Y_LE()).String())) + log.Info(msg, strings.Join(str, "\n")) +} + func main() { + // Use our own ed25519 suite to be able to print x coordinates: + cothority.Suite = edwards25519.NewBlakeSHA256Ed25519() if len(os.Args) < 2 { - log.Fatal("Please give a roster.toml as first parameter") + log.Error("Please give a roster.toml as first parameter") + s := cothority.Suite.Scalar().SetInt64(1) + p := cothority.Suite.Point().Base() + printScalar("* A scalar of '1':", s) + printPoint("* The base point:", p) + printScalar("* A scalar of '2':", s.Add(s, s)) + printPoint("* The base point added to himself:", p.Add(p, p)) + printPoint("* 2 x base:", p.Mul(s, nil)) + var allF0 [32]byte + for i := range allF0 { + allF0[i] = 0xf0 + } + s.SetBytes(allF0[:]) + printScalar("* A reduced all-F0 scalar:", s) + printScalar("* A reduced all-F0 scalar added to itself:", s.Add(s, s)) + return } roster, err := lib.ReadRoster(os.Args[1]) log.ErrFatal(err) diff --git a/ocs/edwards25519/LICENSE b/ocs/edwards25519/LICENSE new file mode 100644 index 0000000000..67697bb743 --- /dev/null +++ b/ocs/edwards25519/LICENSE @@ -0,0 +1,29 @@ +This directory is under the go-license: + +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ocs/edwards25519/allowvt_test.go b/ocs/edwards25519/allowvt_test.go new file mode 100644 index 0000000000..54955b76dd --- /dev/null +++ b/ocs/edwards25519/allowvt_test.go @@ -0,0 +1,20 @@ +package edwards25519 + +import ( + "testing" + + "go.dedis.ch/kyber/v3" +) + +func TestVartime(t *testing.T) { + p := tSuite.Point() + if pvt, ok := p.(kyber.AllowsVarTime); ok { + // Try both settings + pvt.AllowVarTime(false) + p.Mul(one, p) + pvt.AllowVarTime(true) + p.Mul(one, p) + } else { + t.Fatal("expected Point to allow var time") + } +} diff --git a/ocs/edwards25519/const.go b/ocs/edwards25519/const.go new file mode 100644 index 0000000000..bfa2ab4d35 --- /dev/null +++ b/ocs/edwards25519/const.go @@ -0,0 +1,1446 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package edwards25519 + +import ( + "math/big" +) + +// prime modulus of underlying field = 2^255 - 19 +var prime, _ = new(big.Int).SetString("57896044618658097711785492504343953926634992332820282019728792003956564819949", 10) + +// prime order of base Point = 2^252 + 27742317777372353535851937790883648493 +var primeOrder, _ = new(big.Int).SetString("7237005577332262213973186563042994240857116359379907606001950938285454250989", 10) + +// `l_minus_2` is the order of base Point minus two, i.e. 2^252 + +// 27742317777372353535851937790883648493 - 2, in little-endian form +// This is needed to compute constant time modular inversion of scalars. +var lMinus2, _ = new(big.Int).SetString("7237005577332262213973186563042994240857116359379907606001950938285454250987", 10) + +// cofactor of the curve, as a ModInt +var cofactor = new(big.Int).SetInt64(8) + +// order of the full group including the cofactor +var fullOrder = new(big.Int).Mul(primeOrder, cofactor) + +// scalar versions of these, usable for multiplication +var primeOrderScalar = newScalarInt(primeOrder) +var cofactorScalar = newScalarInt(cofactor) + +// identity Point +var nullPoint = new(Point).Null() + +var d = fieldElement{ + -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116, +} + +var d2 = fieldElement{ + -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199, +} + +var sqrtM1 = fieldElement{ + -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482, +} + +var paramA = fieldElement{ + 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0, +} + +var baseext = extendedGroupElement{ + fieldElement{25485296, 5318399, 8791791, -8299916, -14349720, 6939349, -3324311, -7717049, 7287234, -6577708}, + fieldElement{-758052, -1832720, 13046421, -4857925, 6576754, 14371947, -13139572, 6845540, -2198883, -4003719}, + fieldElement{-947565, 6097708, -469190, 10704810, -8556274, -15589498, -16424464, -16608899, 14028613, -5004649}, + fieldElement{6966464, -2456167, 7033433, 6781840, 28785542, 12262365, -2659449, 13959020, -21013759, -5262166}, +} + +var bi = [8]preComputedGroupElement{ + { + fieldElement{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605}, + fieldElement{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378}, + fieldElement{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546}, + }, + { + fieldElement{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024}, + fieldElement{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574}, + fieldElement{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357}, + }, + { + fieldElement{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380}, + fieldElement{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306}, + fieldElement{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942}, + }, + { + fieldElement{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766}, + fieldElement{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701}, + fieldElement{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300}, + }, + { + fieldElement{-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877}, + fieldElement{-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951}, + fieldElement{4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784}, + }, + { + fieldElement{-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436}, + fieldElement{25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918}, + fieldElement{23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877}, + }, + { + fieldElement{-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800}, + fieldElement{-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305}, + fieldElement{-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300}, + }, + { + fieldElement{-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876}, + fieldElement{-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619}, + fieldElement{-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683}, + }, +} + +var base = [32][8]preComputedGroupElement{ + { + { + fieldElement{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605}, + fieldElement{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378}, + fieldElement{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546}, + }, + { + fieldElement{-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303}, + fieldElement{-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081}, + fieldElement{26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697}, + }, + { + fieldElement{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024}, + fieldElement{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574}, + fieldElement{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357}, + }, + { + fieldElement{-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540}, + fieldElement{23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397}, + fieldElement{7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325}, + }, + { + fieldElement{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380}, + fieldElement{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306}, + fieldElement{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942}, + }, + { + fieldElement{-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777}, + fieldElement{-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737}, + fieldElement{-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652}, + }, + { + fieldElement{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766}, + fieldElement{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701}, + fieldElement{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300}, + }, + { + fieldElement{14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726}, + fieldElement{-7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955}, + fieldElement{27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425}, + }, + }, + { + { + fieldElement{-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171}, + fieldElement{27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510}, + fieldElement{17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660}, + }, + { + fieldElement{-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639}, + fieldElement{29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963}, + fieldElement{5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950}, + }, + { + fieldElement{-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568}, + fieldElement{12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335}, + fieldElement{25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628}, + }, + { + fieldElement{-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007}, + fieldElement{-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772}, + fieldElement{-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653}, + }, + { + fieldElement{2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567}, + fieldElement{13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686}, + fieldElement{21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372}, + }, + { + fieldElement{-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887}, + fieldElement{-23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954}, + fieldElement{-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953}, + }, + { + fieldElement{24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833}, + fieldElement{-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532}, + fieldElement{-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876}, + }, + { + fieldElement{2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268}, + fieldElement{33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214}, + fieldElement{1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038}, + }, + }, + { + { + fieldElement{6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800}, + fieldElement{4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645}, + fieldElement{-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664}, + }, + { + fieldElement{1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933}, + fieldElement{-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182}, + fieldElement{-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222}, + }, + { + fieldElement{-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991}, + fieldElement{20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880}, + fieldElement{9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092}, + }, + { + fieldElement{-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295}, + fieldElement{19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788}, + fieldElement{8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553}, + }, + { + fieldElement{-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026}, + fieldElement{11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347}, + fieldElement{-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033}, + }, + { + fieldElement{-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395}, + fieldElement{-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278}, + fieldElement{1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890}, + }, + { + fieldElement{32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995}, + fieldElement{-30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596}, + fieldElement{-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891}, + }, + { + fieldElement{31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060}, + fieldElement{11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608}, + fieldElement{-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606}, + }, + }, + { + { + fieldElement{7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389}, + fieldElement{-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016}, + fieldElement{-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341}, + }, + { + fieldElement{-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505}, + fieldElement{14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553}, + fieldElement{-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655}, + }, + { + fieldElement{15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220}, + fieldElement{12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631}, + fieldElement{-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099}, + }, + { + fieldElement{26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556}, + fieldElement{14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749}, + fieldElement{236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930}, + }, + { + fieldElement{1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391}, + fieldElement{5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253}, + fieldElement{20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066}, + }, + { + fieldElement{24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958}, + fieldElement{-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082}, + fieldElement{-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383}, + }, + { + fieldElement{-30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521}, + fieldElement{-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807}, + fieldElement{23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948}, + }, + { + fieldElement{9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134}, + fieldElement{-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455}, + fieldElement{27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629}, + }, + }, + { + { + fieldElement{-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069}, + fieldElement{-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746}, + fieldElement{24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919}, + }, + { + fieldElement{11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837}, + fieldElement{8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906}, + fieldElement{-28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771}, + }, + { + fieldElement{-25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817}, + fieldElement{10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098}, + fieldElement{10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409}, + }, + { + fieldElement{-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504}, + fieldElement{-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727}, + fieldElement{28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420}, + }, + { + fieldElement{-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003}, + fieldElement{-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605}, + fieldElement{-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384}, + }, + { + fieldElement{-26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701}, + fieldElement{-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683}, + fieldElement{29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708}, + }, + { + fieldElement{-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563}, + fieldElement{-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260}, + fieldElement{-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387}, + }, + { + fieldElement{-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672}, + fieldElement{23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686}, + fieldElement{-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665}, + }, + }, + { + { + fieldElement{11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182}, + fieldElement{-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277}, + fieldElement{14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628}, + }, + { + fieldElement{-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474}, + fieldElement{-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539}, + fieldElement{-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822}, + }, + { + fieldElement{-10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970}, + fieldElement{19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756}, + fieldElement{-24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508}, + }, + { + fieldElement{-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683}, + fieldElement{-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655}, + fieldElement{-20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158}, + }, + { + fieldElement{-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125}, + fieldElement{-15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839}, + fieldElement{-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664}, + }, + { + fieldElement{27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294}, + fieldElement{-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899}, + fieldElement{-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070}, + }, + { + fieldElement{3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294}, + fieldElement{-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949}, + fieldElement{-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083}, + }, + { + fieldElement{31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420}, + fieldElement{-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940}, + fieldElement{29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396}, + }, + }, + { + { + fieldElement{-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567}, + fieldElement{20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127}, + fieldElement{-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294}, + }, + { + fieldElement{-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887}, + fieldElement{22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964}, + fieldElement{16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195}, + }, + { + fieldElement{9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244}, + fieldElement{24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999}, + fieldElement{-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762}, + }, + { + fieldElement{-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274}, + fieldElement{-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236}, + fieldElement{-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605}, + }, + { + fieldElement{-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761}, + fieldElement{-22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884}, + fieldElement{-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482}, + }, + { + fieldElement{-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638}, + fieldElement{-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490}, + fieldElement{-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170}, + }, + { + fieldElement{5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736}, + fieldElement{10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124}, + fieldElement{-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392}, + }, + { + fieldElement{8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029}, + fieldElement{6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048}, + fieldElement{28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958}, + }, + }, + { + { + fieldElement{24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593}, + fieldElement{26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071}, + fieldElement{-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692}, + }, + { + fieldElement{11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687}, + fieldElement{-160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441}, + fieldElement{-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001}, + }, + { + fieldElement{-938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460}, + fieldElement{-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007}, + fieldElement{-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762}, + }, + { + fieldElement{15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005}, + fieldElement{-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674}, + fieldElement{4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035}, + }, + { + fieldElement{7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590}, + fieldElement{-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957}, + fieldElement{-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812}, + }, + { + fieldElement{33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740}, + fieldElement{-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122}, + fieldElement{-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158}, + }, + { + fieldElement{8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885}, + fieldElement{26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140}, + fieldElement{19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857}, + }, + { + fieldElement{801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155}, + fieldElement{19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260}, + fieldElement{19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483}, + }, + }, + { + { + fieldElement{-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677}, + fieldElement{32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815}, + fieldElement{22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751}, + }, + { + fieldElement{-16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203}, + fieldElement{-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208}, + fieldElement{1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230}, + }, + { + fieldElement{16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850}, + fieldElement{-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389}, + fieldElement{-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968}, + }, + { + fieldElement{-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689}, + fieldElement{14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880}, + fieldElement{5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304}, + }, + { + fieldElement{30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632}, + fieldElement{-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412}, + fieldElement{20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566}, + }, + { + fieldElement{-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038}, + fieldElement{-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232}, + fieldElement{-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943}, + }, + { + fieldElement{17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856}, + fieldElement{23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738}, + fieldElement{15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971}, + }, + { + fieldElement{-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718}, + fieldElement{-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697}, + fieldElement{-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883}, + }, + }, + { + { + fieldElement{5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912}, + fieldElement{-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358}, + fieldElement{3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849}, + }, + { + fieldElement{29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307}, + fieldElement{-14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977}, + fieldElement{-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335}, + }, + { + fieldElement{-29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644}, + fieldElement{-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616}, + fieldElement{-27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735}, + }, + { + fieldElement{-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099}, + fieldElement{29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341}, + fieldElement{-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336}, + }, + { + fieldElement{-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646}, + fieldElement{31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425}, + fieldElement{-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388}, + }, + { + fieldElement{-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743}, + fieldElement{-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822}, + fieldElement{-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462}, + }, + { + fieldElement{18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985}, + fieldElement{9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702}, + fieldElement{-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797}, + }, + { + fieldElement{21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293}, + fieldElement{27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100}, + fieldElement{19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688}, + }, + }, + { + { + fieldElement{12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186}, + fieldElement{2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610}, + fieldElement{-2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707}, + }, + { + fieldElement{7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220}, + fieldElement{915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025}, + fieldElement{32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044}, + }, + { + fieldElement{32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992}, + fieldElement{-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027}, + fieldElement{21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197}, + }, + { + fieldElement{8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901}, + fieldElement{31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952}, + fieldElement{19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878}, + }, + { + fieldElement{-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390}, + fieldElement{32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730}, + fieldElement{2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730}, + }, + { + fieldElement{-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180}, + fieldElement{-30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272}, + fieldElement{-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715}, + }, + { + fieldElement{-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970}, + fieldElement{-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772}, + fieldElement{-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865}, + }, + { + fieldElement{15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750}, + fieldElement{20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373}, + fieldElement{32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348}, + }, + }, + { + { + fieldElement{9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144}, + fieldElement{-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195}, + fieldElement{5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086}, + }, + { + fieldElement{-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684}, + fieldElement{-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518}, + fieldElement{-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233}, + }, + { + fieldElement{-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793}, + fieldElement{-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794}, + fieldElement{580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435}, + }, + { + fieldElement{23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921}, + fieldElement{13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518}, + fieldElement{2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563}, + }, + { + fieldElement{14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278}, + fieldElement{-27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024}, + fieldElement{4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030}, + }, + { + fieldElement{10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783}, + fieldElement{27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717}, + fieldElement{6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844}, + }, + { + fieldElement{14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333}, + fieldElement{16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048}, + fieldElement{22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760}, + }, + { + fieldElement{-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760}, + fieldElement{-15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757}, + fieldElement{-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112}, + }, + }, + { + { + fieldElement{-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468}, + fieldElement{3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184}, + fieldElement{10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289}, + }, + { + fieldElement{15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066}, + fieldElement{24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882}, + fieldElement{13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226}, + }, + { + fieldElement{16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101}, + fieldElement{29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279}, + fieldElement{-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811}, + }, + { + fieldElement{27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709}, + fieldElement{20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714}, + fieldElement{-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121}, + }, + { + fieldElement{9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464}, + fieldElement{12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847}, + fieldElement{13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400}, + }, + { + fieldElement{4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414}, + fieldElement{-15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158}, + fieldElement{17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045}, + }, + { + fieldElement{-461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415}, + fieldElement{-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459}, + fieldElement{-31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079}, + }, + { + fieldElement{21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412}, + fieldElement{-20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743}, + fieldElement{-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836}, + }, + }, + { + { + fieldElement{12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022}, + fieldElement{18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429}, + fieldElement{-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065}, + }, + { + fieldElement{30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861}, + fieldElement{10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000}, + fieldElement{-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101}, + }, + { + fieldElement{32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815}, + fieldElement{29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642}, + fieldElement{10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966}, + }, + { + fieldElement{25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574}, + fieldElement{-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742}, + fieldElement{-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689}, + }, + { + fieldElement{12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020}, + fieldElement{-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772}, + fieldElement{3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982}, + }, + { + fieldElement{-14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953}, + fieldElement{-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218}, + fieldElement{-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265}, + }, + { + fieldElement{29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073}, + fieldElement{-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325}, + fieldElement{-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798}, + }, + { + fieldElement{-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870}, + fieldElement{-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863}, + fieldElement{-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927}, + }, + }, + { + { + fieldElement{-2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267}, + fieldElement{-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663}, + fieldElement{22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862}, + }, + { + fieldElement{-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673}, + fieldElement{15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943}, + fieldElement{15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020}, + }, + { + fieldElement{-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238}, + fieldElement{11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064}, + fieldElement{14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795}, + }, + { + fieldElement{15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052}, + fieldElement{-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904}, + fieldElement{29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531}, + }, + { + fieldElement{-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979}, + fieldElement{-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841}, + fieldElement{10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431}, + }, + { + fieldElement{10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324}, + fieldElement{-31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940}, + fieldElement{10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320}, + }, + { + fieldElement{-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184}, + fieldElement{14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114}, + fieldElement{30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878}, + }, + { + fieldElement{12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784}, + fieldElement{-2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091}, + fieldElement{-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585}, + }, + }, + { + { + fieldElement{-8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208}, + fieldElement{10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864}, + fieldElement{17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661}, + }, + { + fieldElement{7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233}, + fieldElement{26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212}, + fieldElement{-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525}, + }, + { + fieldElement{-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068}, + fieldElement{9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397}, + fieldElement{-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988}, + }, + { + fieldElement{5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889}, + fieldElement{32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038}, + fieldElement{14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697}, + }, + { + fieldElement{20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875}, + fieldElement{-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905}, + fieldElement{-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656}, + }, + { + fieldElement{11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818}, + fieldElement{27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714}, + fieldElement{10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203}, + }, + { + fieldElement{20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931}, + fieldElement{-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024}, + fieldElement{-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084}, + }, + { + fieldElement{-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204}, + fieldElement{20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817}, + fieldElement{27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667}, + }, + }, + { + { + fieldElement{11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504}, + fieldElement{-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768}, + fieldElement{-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255}, + }, + { + fieldElement{6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790}, + fieldElement{1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438}, + fieldElement{-22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333}, + }, + { + fieldElement{17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971}, + fieldElement{31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905}, + fieldElement{29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409}, + }, + { + fieldElement{12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409}, + fieldElement{6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499}, + fieldElement{-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363}, + }, + { + fieldElement{28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664}, + fieldElement{-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324}, + fieldElement{-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940}, + }, + { + fieldElement{13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990}, + fieldElement{-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914}, + fieldElement{-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290}, + }, + { + fieldElement{24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257}, + fieldElement{-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433}, + fieldElement{-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236}, + }, + { + fieldElement{-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045}, + fieldElement{11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093}, + fieldElement{-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347}, + }, + }, + { + { + fieldElement{-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191}, + fieldElement{-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507}, + fieldElement{-12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906}, + }, + { + fieldElement{3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018}, + fieldElement{-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109}, + fieldElement{-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926}, + }, + { + fieldElement{-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528}, + fieldElement{8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625}, + fieldElement{-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286}, + }, + { + fieldElement{2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033}, + fieldElement{27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866}, + fieldElement{21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896}, + }, + { + fieldElement{30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075}, + fieldElement{26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347}, + fieldElement{-22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437}, + }, + { + fieldElement{-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165}, + fieldElement{-18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588}, + fieldElement{-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193}, + }, + { + fieldElement{-19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017}, + fieldElement{-28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883}, + fieldElement{21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961}, + }, + { + fieldElement{8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043}, + fieldElement{29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663}, + fieldElement{-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362}, + }, + }, + { + { + fieldElement{-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860}, + fieldElement{2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466}, + fieldElement{-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063}, + }, + { + fieldElement{-26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997}, + fieldElement{-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295}, + fieldElement{-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369}, + }, + { + fieldElement{9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385}, + fieldElement{18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109}, + fieldElement{2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906}, + }, + { + fieldElement{4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424}, + fieldElement{-19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185}, + fieldElement{7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962}, + }, + { + fieldElement{-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325}, + fieldElement{10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593}, + fieldElement{696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404}, + }, + { + fieldElement{-11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644}, + fieldElement{17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801}, + fieldElement{26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804}, + }, + { + fieldElement{-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884}, + fieldElement{-586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577}, + fieldElement{-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849}, + }, + { + fieldElement{32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473}, + fieldElement{-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644}, + fieldElement{-2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319}, + }, + }, + { + { + fieldElement{-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599}, + fieldElement{-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768}, + fieldElement{-27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084}, + }, + { + fieldElement{-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328}, + fieldElement{-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369}, + fieldElement{20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920}, + }, + { + fieldElement{12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815}, + fieldElement{-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025}, + fieldElement{-21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397}, + }, + { + fieldElement{-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448}, + fieldElement{6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981}, + fieldElement{30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165}, + }, + { + fieldElement{32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501}, + fieldElement{17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073}, + fieldElement{-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861}, + }, + { + fieldElement{14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845}, + fieldElement{-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211}, + fieldElement{18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870}, + }, + { + fieldElement{10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096}, + fieldElement{33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803}, + fieldElement{-32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168}, + }, + { + fieldElement{30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965}, + fieldElement{-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505}, + fieldElement{18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598}, + }, + }, + { + { + fieldElement{5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782}, + fieldElement{5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900}, + fieldElement{-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479}, + }, + { + fieldElement{-12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208}, + fieldElement{8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232}, + fieldElement{17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719}, + }, + { + fieldElement{16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271}, + fieldElement{-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326}, + fieldElement{-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132}, + }, + { + fieldElement{14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300}, + fieldElement{8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570}, + fieldElement{15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670}, + }, + { + fieldElement{-2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994}, + fieldElement{-12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913}, + fieldElement{31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317}, + }, + { + fieldElement{-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730}, + fieldElement{842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096}, + fieldElement{-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078}, + }, + { + fieldElement{-15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411}, + fieldElement{-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905}, + fieldElement{-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654}, + }, + { + fieldElement{-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870}, + fieldElement{-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498}, + fieldElement{12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579}, + }, + }, + { + { + fieldElement{14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677}, + fieldElement{10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647}, + fieldElement{-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743}, + }, + { + fieldElement{-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468}, + fieldElement{21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375}, + fieldElement{-25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155}, + }, + { + fieldElement{6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725}, + fieldElement{-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612}, + fieldElement{-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943}, + }, + { + fieldElement{-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944}, + fieldElement{30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928}, + fieldElement{9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406}, + }, + { + fieldElement{22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139}, + fieldElement{-8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963}, + fieldElement{-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693}, + }, + { + fieldElement{1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734}, + fieldElement{-448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680}, + fieldElement{-24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410}, + }, + { + fieldElement{-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931}, + fieldElement{-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654}, + fieldElement{22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710}, + }, + { + fieldElement{29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180}, + fieldElement{-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684}, + fieldElement{-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895}, + }, + }, + { + { + fieldElement{22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501}, + fieldElement{-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413}, + fieldElement{6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880}, + }, + { + fieldElement{-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874}, + fieldElement{22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962}, + fieldElement{-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899}, + }, + { + fieldElement{21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152}, + fieldElement{9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063}, + fieldElement{7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080}, + }, + { + fieldElement{-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146}, + fieldElement{-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183}, + fieldElement{-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133}, + }, + { + fieldElement{-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421}, + fieldElement{-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622}, + fieldElement{-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197}, + }, + { + fieldElement{2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663}, + fieldElement{31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753}, + fieldElement{4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755}, + }, + { + fieldElement{-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862}, + fieldElement{-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118}, + fieldElement{26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171}, + }, + { + fieldElement{15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380}, + fieldElement{16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824}, + fieldElement{28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270}, + }, + }, + { + { + fieldElement{-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438}, + fieldElement{-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584}, + fieldElement{-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562}, + }, + { + fieldElement{30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471}, + fieldElement{18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610}, + fieldElement{19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269}, + }, + { + fieldElement{-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650}, + fieldElement{14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369}, + fieldElement{19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461}, + }, + { + fieldElement{30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462}, + fieldElement{-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793}, + fieldElement{-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218}, + }, + { + fieldElement{-24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226}, + fieldElement{18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019}, + fieldElement{-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037}, + }, + { + fieldElement{31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171}, + fieldElement{-17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132}, + fieldElement{-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841}, + }, + { + fieldElement{21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181}, + fieldElement{-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210}, + fieldElement{-1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040}, + }, + { + fieldElement{3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935}, + fieldElement{24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105}, + fieldElement{-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814}, + }, + }, + { + { + fieldElement{793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852}, + fieldElement{5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581}, + fieldElement{-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646}, + }, + { + fieldElement{10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844}, + fieldElement{10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025}, + fieldElement{27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453}, + }, + { + fieldElement{-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068}, + fieldElement{4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192}, + fieldElement{-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921}, + }, + { + fieldElement{-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259}, + fieldElement{-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426}, + fieldElement{-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072}, + }, + { + fieldElement{-17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305}, + fieldElement{13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832}, + fieldElement{28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943}, + }, + { + fieldElement{-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011}, + fieldElement{24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447}, + fieldElement{17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494}, + }, + { + fieldElement{-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245}, + fieldElement{-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859}, + fieldElement{28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915}, + }, + { + fieldElement{16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707}, + fieldElement{10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848}, + fieldElement{-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224}, + }, + }, + { + { + fieldElement{-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391}, + fieldElement{15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215}, + fieldElement{-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101}, + }, + { + fieldElement{23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713}, + fieldElement{21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849}, + fieldElement{-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930}, + }, + { + fieldElement{-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940}, + fieldElement{-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031}, + fieldElement{-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404}, + }, + { + fieldElement{-25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243}, + fieldElement{-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116}, + fieldElement{-24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525}, + }, + { + fieldElement{-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509}, + fieldElement{-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883}, + fieldElement{15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865}, + }, + { + fieldElement{-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660}, + fieldElement{4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273}, + fieldElement{-28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138}, + }, + { + fieldElement{-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560}, + fieldElement{-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135}, + fieldElement{2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941}, + }, + { + fieldElement{-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739}, + fieldElement{18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756}, + fieldElement{-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819}, + }, + }, + { + { + fieldElement{-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347}, + fieldElement{-27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028}, + fieldElement{21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075}, + }, + { + fieldElement{16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799}, + fieldElement{-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609}, + fieldElement{-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817}, + }, + { + fieldElement{-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989}, + fieldElement{-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523}, + fieldElement{4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278}, + }, + { + fieldElement{31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045}, + fieldElement{19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377}, + fieldElement{24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480}, + }, + { + fieldElement{17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016}, + fieldElement{510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426}, + fieldElement{18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525}, + }, + { + fieldElement{13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396}, + fieldElement{9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080}, + fieldElement{12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892}, + }, + { + fieldElement{15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275}, + fieldElement{11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074}, + fieldElement{20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140}, + }, + { + fieldElement{-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717}, + fieldElement{-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101}, + fieldElement{24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127}, + }, + }, + { + { + fieldElement{-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632}, + fieldElement{-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415}, + fieldElement{-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160}, + }, + { + fieldElement{31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876}, + fieldElement{22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625}, + fieldElement{-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478}, + }, + { + fieldElement{27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164}, + fieldElement{26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595}, + fieldElement{-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248}, + }, + { + fieldElement{-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858}, + fieldElement{15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193}, + fieldElement{8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184}, + }, + { + fieldElement{-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942}, + fieldElement{-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635}, + fieldElement{21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948}, + }, + { + fieldElement{11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935}, + fieldElement{-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415}, + fieldElement{-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416}, + }, + { + fieldElement{-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018}, + fieldElement{4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778}, + fieldElement{366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659}, + }, + { + fieldElement{-24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385}, + fieldElement{18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503}, + fieldElement{476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329}, + }, + }, + { + { + fieldElement{20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056}, + fieldElement{-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838}, + fieldElement{24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948}, + }, + { + fieldElement{-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691}, + fieldElement{-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118}, + fieldElement{-23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517}, + }, + { + fieldElement{-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269}, + fieldElement{-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904}, + fieldElement{-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589}, + }, + { + fieldElement{-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193}, + fieldElement{-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910}, + fieldElement{-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930}, + }, + { + fieldElement{-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667}, + fieldElement{25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481}, + fieldElement{-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876}, + }, + { + fieldElement{22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640}, + fieldElement{-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278}, + fieldElement{-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112}, + }, + { + fieldElement{26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272}, + fieldElement{17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012}, + fieldElement{-10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221}, + }, + { + fieldElement{30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046}, + fieldElement{13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345}, + fieldElement{-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310}, + }, + }, + { + { + fieldElement{19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937}, + fieldElement{31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636}, + fieldElement{-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008}, + }, + { + fieldElement{-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429}, + fieldElement{-15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576}, + fieldElement{31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066}, + }, + { + fieldElement{-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490}, + fieldElement{-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104}, + fieldElement{33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053}, + }, + { + fieldElement{31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275}, + fieldElement{-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511}, + fieldElement{22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095}, + }, + { + fieldElement{-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439}, + fieldElement{23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939}, + fieldElement{-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424}, + }, + { + fieldElement{2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310}, + fieldElement{3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608}, + fieldElement{-32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079}, + }, + { + fieldElement{-23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101}, + fieldElement{21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418}, + fieldElement{18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576}, + }, + { + fieldElement{30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356}, + fieldElement{9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996}, + fieldElement{-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099}, + }, + }, + { + { + fieldElement{-26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728}, + fieldElement{-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658}, + fieldElement{-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242}, + }, + { + fieldElement{-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001}, + fieldElement{-4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766}, + fieldElement{18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373}, + }, + { + fieldElement{26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458}, + fieldElement{-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628}, + fieldElement{-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657}, + }, + { + fieldElement{-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062}, + fieldElement{25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616}, + fieldElement{31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014}, + }, + { + fieldElement{24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383}, + fieldElement{-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814}, + fieldElement{-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718}, + }, + { + fieldElement{30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417}, + fieldElement{2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222}, + fieldElement{33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444}, + }, + { + fieldElement{-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597}, + fieldElement{23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970}, + fieldElement{1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799}, + }, + { + fieldElement{-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647}, + fieldElement{13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511}, + fieldElement{-29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032}, + }, + }, + { + { + fieldElement{9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834}, + fieldElement{-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461}, + fieldElement{29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062}, + }, + { + fieldElement{-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516}, + fieldElement{-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547}, + fieldElement{-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240}, + }, + { + fieldElement{-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038}, + fieldElement{-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741}, + fieldElement{16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103}, + }, + { + fieldElement{-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747}, + fieldElement{-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323}, + fieldElement{31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016}, + }, + { + fieldElement{-14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373}, + fieldElement{15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228}, + fieldElement{-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141}, + }, + { + fieldElement{16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399}, + fieldElement{11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831}, + fieldElement{-185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376}, + }, + { + fieldElement{-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313}, + fieldElement{-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958}, + fieldElement{-6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577}, + }, + { + fieldElement{-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743}, + fieldElement{29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684}, + fieldElement{-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476}, + }, + }, +} diff --git a/ocs/edwards25519/curve.go b/ocs/edwards25519/curve.go new file mode 100644 index 0000000000..0620a708a0 --- /dev/null +++ b/ocs/edwards25519/curve.go @@ -0,0 +1,60 @@ +package edwards25519 + +import ( + "crypto/cipher" + "crypto/sha512" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/util/random" +) + +// Curve represents the Ed25519 group. +// There are no parameters and no initialization is required +// because it supports only this one specific curve. +type Curve struct { +} + +// Return the name of the curve, "Ed25519". +func (c *Curve) String() string { + return "Ed25519" +} + +// ScalarLen returns 32, the size in bytes of an encoded Scalar +// for the Ed25519 curve. +func (c *Curve) ScalarLen() int { + return 32 +} + +// Scalar creates a new Scalar for the prime-order subgroup of the Ed25519 curve. +// The scalars in this package implement kyber.Scalar's SetBytes +// method, interpreting the bytes as a little-endian integer, in order to remain +// compatible with other Ed25519 implementations, and with the standard implementation +// of the EdDSA signature. +func (c *Curve) Scalar() kyber.Scalar { + return &scalar{} +} + +// PointLen returns 32, the size in bytes of an encoded Point on the Ed25519 curve. +func (c *Curve) PointLen() int { + return 32 +} + +// Point creates a new Point on the Ed25519 curve. +func (c *Curve) Point() kyber.Point { + P := new(Point) + return P +} + +// NewKey returns a formatted Ed25519 key (avoiding subgroup attack by requiring +// it to be a multiple of 8). NewKey implements the kyber/util/key.Generator interface. +func (c *Curve) NewKey(stream cipher.Stream) kyber.Scalar { + var buffer [32]byte + random.Bytes(buffer[:], stream) + scalar := sha512.Sum512(buffer[:]) + scalar[0] &= 0xf8 + scalar[31] &= 0x7f + scalar[31] |= 0x40 + + secret := c.Scalar().SetBytes(scalar[:32]) + return secret +} diff --git a/ocs/edwards25519/curve_test.go b/ocs/edwards25519/curve_test.go new file mode 100644 index 0000000000..2ffb66d695 --- /dev/null +++ b/ocs/edwards25519/curve_test.go @@ -0,0 +1,31 @@ +package edwards25519 + +import ( + "testing" + + "go.dedis.ch/kyber/v3/util/test" +) + +var tSuite = NewBlakeSHA256Ed25519() +var groupBench = test.NewGroupBench(tSuite) + +func TestSuite(t *testing.T) { test.SuiteTest(t, tSuite) } + +func BenchmarkScalarAdd(b *testing.B) { groupBench.ScalarAdd(b.N) } +func BenchmarkScalarSub(b *testing.B) { groupBench.ScalarSub(b.N) } +func BenchmarkScalarNeg(b *testing.B) { groupBench.ScalarNeg(b.N) } +func BenchmarkScalarMul(b *testing.B) { groupBench.ScalarMul(b.N) } +func BenchmarkScalarDiv(b *testing.B) { groupBench.ScalarDiv(b.N) } +func BenchmarkScalarInv(b *testing.B) { groupBench.ScalarInv(b.N) } +func BenchmarkScalarPick(b *testing.B) { groupBench.ScalarPick(b.N) } +func BenchmarkScalarEncode(b *testing.B) { groupBench.ScalarEncode(b.N) } +func BenchmarkScalarDecode(b *testing.B) { groupBench.ScalarDecode(b.N) } + +func BenchmarkPointAdd(b *testing.B) { groupBench.PointAdd(b.N) } +func BenchmarkPointSub(b *testing.B) { groupBench.PointSub(b.N) } +func BenchmarkPointNeg(b *testing.B) { groupBench.PointNeg(b.N) } +func BenchmarkPointMul(b *testing.B) { groupBench.PointMul(b.N) } +func BenchmarkPointBaseMul(b *testing.B) { groupBench.PointBaseMul(b.N) } +func BenchmarkPointPick(b *testing.B) { groupBench.PointPick(b.N) } +func BenchmarkPointEncode(b *testing.B) { groupBench.PointEncode(b.N) } +func BenchmarkPointDecode(b *testing.B) { groupBench.PointDecode(b.N) } diff --git a/ocs/edwards25519/fe.go b/ocs/edwards25519/fe.go new file mode 100644 index 0000000000..53565ad0b7 --- /dev/null +++ b/ocs/edwards25519/fe.go @@ -0,0 +1,986 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package edwards25519 + +import ( + "fmt" +) + +// This code is a port of the public domain, "ref10" implementation of ed25519 +// from SUPERCOP. + +// fieldElement represents an element of the field GF(2^255 - 19). An element +// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 +// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on +// context. +type fieldElement [10]int32 + +func feZero(fe *fieldElement) { + for i := range fe { + fe[i] = 0 + } +} + +func feOne(fe *fieldElement) { + feZero(fe) + fe[0] = 1 +} + +func feAdd(dst, a, b *fieldElement) { + for i := range dst { + dst[i] = a[i] + b[i] + } +} + +func feSub(dst, a, b *fieldElement) { + for i := range dst { + dst[i] = a[i] - b[i] + } +} + +func feCopy(dst, src *fieldElement) { + for i := range dst { + dst[i] = src[i] + } +} + +// Replace (f,g) with (g,g) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +func feCMove(f, g *fieldElement, b int32) { + var x fieldElement + b = -b + for i := range x { + x[i] = b & (f[i] ^ g[i]) + } + for i := range f { + f[i] ^= x[i] + } +} + +func load3(in []byte) int64 { + r := int64(in[0]) + r |= int64(in[1]) << 8 + r |= int64(in[2]) << 16 + return r +} + +func load4(in []byte) int64 { + r := int64(in[0]) + r |= int64(in[1]) << 8 + r |= int64(in[2]) << 16 + r |= int64(in[3]) << 24 + return r +} + +func feFromBytes(dst *fieldElement, src []byte) { + h0 := load4(src[:]) + h1 := load3(src[4:]) << 6 + h2 := load3(src[7:]) << 5 + h3 := load3(src[10:]) << 3 + h4 := load3(src[13:]) << 2 + h5 := load4(src[16:]) + h6 := load3(src[20:]) << 7 + h7 := load3(src[23:]) << 5 + h8 := load3(src[26:]) << 4 + h9 := (load3(src[29:]) & 8388607) << 2 + + var carry [10]int64 + carry[9] = (h9 + 1<<24) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + carry[1] = (h1 + 1<<24) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[3] = (h3 + 1<<24) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[5] = (h5 + 1<<24) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + carry[7] = (h7 + 1<<24) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[0] = (h0 + 1<<25) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[2] = (h2 + 1<<25) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[4] = (h4 + 1<<25) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[6] = (h6 + 1<<25) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + carry[8] = (h8 + 1<<25) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + dst[0] = int32(h0) + dst[1] = int32(h1) + dst[2] = int32(h2) + dst[3] = int32(h3) + dst[4] = int32(h4) + dst[5] = int32(h5) + dst[6] = int32(h6) + dst[7] = int32(h7) + dst[8] = int32(h8) + dst[9] = int32(h9) +} + +// feToBytes marshals h to s. +// Preconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Write p=2^255-19; q=floor(h/p). +// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). +// +// Proof: +// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. +// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4. +// +// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). +// Then 0> 25 + q = (h[0] + q) >> 26 + q = (h[1] + q) >> 25 + q = (h[2] + q) >> 26 + q = (h[3] + q) >> 25 + q = (h[4] + q) >> 26 + q = (h[5] + q) >> 25 + q = (h[6] + q) >> 26 + q = (h[7] + q) >> 25 + q = (h[8] + q) >> 26 + q = (h[9] + q) >> 25 + + // Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. + h[0] += 19 * q + // Goal: Output h-2^255 q, which is between 0 and 2^255-20. + + carry[0] = h[0] >> 26 + h[1] += carry[0] + h[0] -= carry[0] << 26 + carry[1] = h[1] >> 25 + h[2] += carry[1] + h[1] -= carry[1] << 25 + carry[2] = h[2] >> 26 + h[3] += carry[2] + h[2] -= carry[2] << 26 + carry[3] = h[3] >> 25 + h[4] += carry[3] + h[3] -= carry[3] << 25 + carry[4] = h[4] >> 26 + h[5] += carry[4] + h[4] -= carry[4] << 26 + carry[5] = h[5] >> 25 + h[6] += carry[5] + h[5] -= carry[5] << 25 + carry[6] = h[6] >> 26 + h[7] += carry[6] + h[6] -= carry[6] << 26 + carry[7] = h[7] >> 25 + h[8] += carry[7] + h[7] -= carry[7] << 25 + carry[8] = h[8] >> 26 + h[9] += carry[8] + h[8] -= carry[8] << 26 + carry[9] = h[9] >> 25 + h[9] -= carry[9] << 25 + // h10 = carry9 + + // Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + // Have h[0]+...+2^230 h[9] between 0 and 2^255-1; + // evidently 2^255 h10-2^255 q = 0. + // Goal: Output h[0]+...+2^230 h[9]. + + s[0] = byte(h[0] >> 0) + s[1] = byte(h[0] >> 8) + s[2] = byte(h[0] >> 16) + s[3] = byte((h[0] >> 24) | (h[1] << 2)) + s[4] = byte(h[1] >> 6) + s[5] = byte(h[1] >> 14) + s[6] = byte((h[1] >> 22) | (h[2] << 3)) + s[7] = byte(h[2] >> 5) + s[8] = byte(h[2] >> 13) + s[9] = byte((h[2] >> 21) | (h[3] << 5)) + s[10] = byte(h[3] >> 3) + s[11] = byte(h[3] >> 11) + s[12] = byte((h[3] >> 19) | (h[4] << 6)) + s[13] = byte(h[4] >> 2) + s[14] = byte(h[4] >> 10) + s[15] = byte(h[4] >> 18) + s[16] = byte(h[5] >> 0) + s[17] = byte(h[5] >> 8) + s[18] = byte(h[5] >> 16) + s[19] = byte((h[5] >> 24) | (h[6] << 1)) + s[20] = byte(h[6] >> 7) + s[21] = byte(h[6] >> 15) + s[22] = byte((h[6] >> 23) | (h[7] << 3)) + s[23] = byte(h[7] >> 5) + s[24] = byte(h[7] >> 13) + s[25] = byte((h[7] >> 21) | (h[8] << 4)) + s[26] = byte(h[8] >> 4) + s[27] = byte(h[8] >> 12) + s[28] = byte((h[8] >> 20) | (h[9] << 6)) + s[29] = byte(h[9] >> 2) + s[30] = byte(h[9] >> 10) + s[31] = byte(h[9] >> 18) +} + +func feIsNegative(f *fieldElement) byte { + var s [32]byte + feToBytes(&s, f) + return s[0] & 1 +} + +func feIsNonZero(f *fieldElement) int32 { + var s [32]byte + feToBytes(&s, f) + var x uint8 + for _, b := range s { + x |= b + } + x |= x >> 4 + x |= x >> 2 + x |= x >> 1 + return int32(x & 1) +} + +// feNeg sets h = -f +// +// Preconditions: +// |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +func feNeg(h, f *fieldElement) { + for i := range h { + h[i] = -f[i] + } +} + +// feMul calculates h = f * g +// Can overlap h with f or g. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Notes on implementation strategy: +// +// Using schoolbook multiplication. +// Karatsuba would save a little in some cost models. +// +// Most multiplications by 2 and 19 are 32-bit precomputations; +// cheaper than 64-bit postcomputations. +// +// There is one remaining multiplication by 19 in the carry chain; +// one *19 precomputation can be merged into this, +// but the resulting data flow is considerably less clean. +// +// There are 12 carries below. +// 10 of them are 2-way parallelizable and vectorizable. +// Can get away with 11 carries, but then data flow is much deeper. +// +// With tighter constraints on inputs can squeeze carries into int32. +func feMul(h, f, g *fieldElement) { + f0 := f[0] + f1 := f[1] + f2 := f[2] + f3 := f[3] + f4 := f[4] + f5 := f[5] + f6 := f[6] + f7 := f[7] + f8 := f[8] + f9 := f[9] + g0 := g[0] + g1 := g[1] + g2 := g[2] + g3 := g[3] + g4 := g[4] + g5 := g[5] + g6 := g[6] + g7 := g[7] + g8 := g[8] + g9 := g[9] + g1_19 := 19 * g1 /* 1.4*2^29 */ + g2_19 := 19 * g2 /* 1.4*2^30; still ok */ + g3_19 := 19 * g3 + g4_19 := 19 * g4 + g5_19 := 19 * g5 + g6_19 := 19 * g6 + g7_19 := 19 * g7 + g8_19 := 19 * g8 + g9_19 := 19 * g9 + f1_2 := 2 * f1 + f3_2 := 2 * f3 + f5_2 := 2 * f5 + f7_2 := 2 * f7 + f9_2 := 2 * f9 + f0g0 := int64(f0) * int64(g0) + f0g1 := int64(f0) * int64(g1) + f0g2 := int64(f0) * int64(g2) + f0g3 := int64(f0) * int64(g3) + f0g4 := int64(f0) * int64(g4) + f0g5 := int64(f0) * int64(g5) + f0g6 := int64(f0) * int64(g6) + f0g7 := int64(f0) * int64(g7) + f0g8 := int64(f0) * int64(g8) + f0g9 := int64(f0) * int64(g9) + f1g0 := int64(f1) * int64(g0) + f1g1_2 := int64(f1_2) * int64(g1) + f1g2 := int64(f1) * int64(g2) + f1g3_2 := int64(f1_2) * int64(g3) + f1g4 := int64(f1) * int64(g4) + f1g5_2 := int64(f1_2) * int64(g5) + f1g6 := int64(f1) * int64(g6) + f1g7_2 := int64(f1_2) * int64(g7) + f1g8 := int64(f1) * int64(g8) + f1g9_38 := int64(f1_2) * int64(g9_19) + f2g0 := int64(f2) * int64(g0) + f2g1 := int64(f2) * int64(g1) + f2g2 := int64(f2) * int64(g2) + f2g3 := int64(f2) * int64(g3) + f2g4 := int64(f2) * int64(g4) + f2g5 := int64(f2) * int64(g5) + f2g6 := int64(f2) * int64(g6) + f2g7 := int64(f2) * int64(g7) + f2g8_19 := int64(f2) * int64(g8_19) + f2g9_19 := int64(f2) * int64(g9_19) + f3g0 := int64(f3) * int64(g0) + f3g1_2 := int64(f3_2) * int64(g1) + f3g2 := int64(f3) * int64(g2) + f3g3_2 := int64(f3_2) * int64(g3) + f3g4 := int64(f3) * int64(g4) + f3g5_2 := int64(f3_2) * int64(g5) + f3g6 := int64(f3) * int64(g6) + f3g7_38 := int64(f3_2) * int64(g7_19) + f3g8_19 := int64(f3) * int64(g8_19) + f3g9_38 := int64(f3_2) * int64(g9_19) + f4g0 := int64(f4) * int64(g0) + f4g1 := int64(f4) * int64(g1) + f4g2 := int64(f4) * int64(g2) + f4g3 := int64(f4) * int64(g3) + f4g4 := int64(f4) * int64(g4) + f4g5 := int64(f4) * int64(g5) + f4g6_19 := int64(f4) * int64(g6_19) + f4g7_19 := int64(f4) * int64(g7_19) + f4g8_19 := int64(f4) * int64(g8_19) + f4g9_19 := int64(f4) * int64(g9_19) + f5g0 := int64(f5) * int64(g0) + f5g1_2 := int64(f5_2) * int64(g1) + f5g2 := int64(f5) * int64(g2) + f5g3_2 := int64(f5_2) * int64(g3) + f5g4 := int64(f5) * int64(g4) + f5g5_38 := int64(f5_2) * int64(g5_19) + f5g6_19 := int64(f5) * int64(g6_19) + f5g7_38 := int64(f5_2) * int64(g7_19) + f5g8_19 := int64(f5) * int64(g8_19) + f5g9_38 := int64(f5_2) * int64(g9_19) + f6g0 := int64(f6) * int64(g0) + f6g1 := int64(f6) * int64(g1) + f6g2 := int64(f6) * int64(g2) + f6g3 := int64(f6) * int64(g3) + f6g4_19 := int64(f6) * int64(g4_19) + f6g5_19 := int64(f6) * int64(g5_19) + f6g6_19 := int64(f6) * int64(g6_19) + f6g7_19 := int64(f6) * int64(g7_19) + f6g8_19 := int64(f6) * int64(g8_19) + f6g9_19 := int64(f6) * int64(g9_19) + f7g0 := int64(f7) * int64(g0) + f7g1_2 := int64(f7_2) * int64(g1) + f7g2 := int64(f7) * int64(g2) + f7g3_38 := int64(f7_2) * int64(g3_19) + f7g4_19 := int64(f7) * int64(g4_19) + f7g5_38 := int64(f7_2) * int64(g5_19) + f7g6_19 := int64(f7) * int64(g6_19) + f7g7_38 := int64(f7_2) * int64(g7_19) + f7g8_19 := int64(f7) * int64(g8_19) + f7g9_38 := int64(f7_2) * int64(g9_19) + f8g0 := int64(f8) * int64(g0) + f8g1 := int64(f8) * int64(g1) + f8g2_19 := int64(f8) * int64(g2_19) + f8g3_19 := int64(f8) * int64(g3_19) + f8g4_19 := int64(f8) * int64(g4_19) + f8g5_19 := int64(f8) * int64(g5_19) + f8g6_19 := int64(f8) * int64(g6_19) + f8g7_19 := int64(f8) * int64(g7_19) + f8g8_19 := int64(f8) * int64(g8_19) + f8g9_19 := int64(f8) * int64(g9_19) + f9g0 := int64(f9) * int64(g0) + f9g1_38 := int64(f9_2) * int64(g1_19) + f9g2_19 := int64(f9) * int64(g2_19) + f9g3_38 := int64(f9_2) * int64(g3_19) + f9g4_19 := int64(f9) * int64(g4_19) + f9g5_38 := int64(f9_2) * int64(g5_19) + f9g6_19 := int64(f9) * int64(g6_19) + f9g7_38 := int64(f9_2) * int64(g7_19) + f9g8_19 := int64(f9) * int64(g8_19) + f9g9_38 := int64(f9_2) * int64(g9_19) + h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38 + h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19 + h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38 + h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19 + h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38 + h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19 + h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38 + h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19 + h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38 + h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 + var carry [10]int64 + + /* + |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38)) + i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8 + |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19)) + i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9 + */ + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + /* |h0| <= 2^25 */ + /* |h4| <= 2^25 */ + /* |h1| <= 1.51*2^58 */ + /* |h5| <= 1.51*2^58 */ + + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + /* |h1| <= 2^24; from now on fits into int32 */ + /* |h5| <= 2^24; from now on fits into int32 */ + /* |h2| <= 1.21*2^59 */ + /* |h6| <= 1.21*2^59 */ + + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + /* |h2| <= 2^25; from now on fits into int32 unchanged */ + /* |h6| <= 2^25; from now on fits into int32 unchanged */ + /* |h3| <= 1.51*2^58 */ + /* |h7| <= 1.51*2^58 */ + + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + /* |h3| <= 2^24; from now on fits into int32 unchanged */ + /* |h7| <= 2^24; from now on fits into int32 unchanged */ + /* |h4| <= 1.52*2^33 */ + /* |h8| <= 1.52*2^33 */ + + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + /* |h4| <= 2^25; from now on fits into int32 unchanged */ + /* |h8| <= 2^25; from now on fits into int32 unchanged */ + /* |h5| <= 1.01*2^24 */ + /* |h9| <= 1.51*2^58 */ + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + /* |h9| <= 2^24; from now on fits into int32 unchanged */ + /* |h0| <= 1.8*2^37 */ + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + /* |h0| <= 2^25; from now on fits into int32 unchanged */ + /* |h1| <= 1.01*2^24 */ + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// feSquare calculates h = f*f. Can overlap h with f. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +func feSquare(h, f *fieldElement) { + f0 := f[0] + f1 := f[1] + f2 := f[2] + f3 := f[3] + f4 := f[4] + f5 := f[5] + f6 := f[6] + f7 := f[7] + f8 := f[8] + f9 := f[9] + f0_2 := 2 * f0 + f1_2 := 2 * f1 + f2_2 := 2 * f2 + f3_2 := 2 * f3 + f4_2 := 2 * f4 + f5_2 := 2 * f5 + f6_2 := 2 * f6 + f7_2 := 2 * f7 + f5_38 := 38 * f5 // 1.31*2^30 + f6_19 := 19 * f6 // 1.31*2^30 + f7_38 := 38 * f7 // 1.31*2^30 + f8_19 := 19 * f8 // 1.31*2^30 + f9_38 := 38 * f9 // 1.31*2^30 + f0f0 := int64(f0) * int64(f0) + f0f1_2 := int64(f0_2) * int64(f1) + f0f2_2 := int64(f0_2) * int64(f2) + f0f3_2 := int64(f0_2) * int64(f3) + f0f4_2 := int64(f0_2) * int64(f4) + f0f5_2 := int64(f0_2) * int64(f5) + f0f6_2 := int64(f0_2) * int64(f6) + f0f7_2 := int64(f0_2) * int64(f7) + f0f8_2 := int64(f0_2) * int64(f8) + f0f9_2 := int64(f0_2) * int64(f9) + f1f1_2 := int64(f1_2) * int64(f1) + f1f2_2 := int64(f1_2) * int64(f2) + f1f3_4 := int64(f1_2) * int64(f3_2) + f1f4_2 := int64(f1_2) * int64(f4) + f1f5_4 := int64(f1_2) * int64(f5_2) + f1f6_2 := int64(f1_2) * int64(f6) + f1f7_4 := int64(f1_2) * int64(f7_2) + f1f8_2 := int64(f1_2) * int64(f8) + f1f9_76 := int64(f1_2) * int64(f9_38) + f2f2 := int64(f2) * int64(f2) + f2f3_2 := int64(f2_2) * int64(f3) + f2f4_2 := int64(f2_2) * int64(f4) + f2f5_2 := int64(f2_2) * int64(f5) + f2f6_2 := int64(f2_2) * int64(f6) + f2f7_2 := int64(f2_2) * int64(f7) + f2f8_38 := int64(f2_2) * int64(f8_19) + f2f9_38 := int64(f2) * int64(f9_38) + f3f3_2 := int64(f3_2) * int64(f3) + f3f4_2 := int64(f3_2) * int64(f4) + f3f5_4 := int64(f3_2) * int64(f5_2) + f3f6_2 := int64(f3_2) * int64(f6) + f3f7_76 := int64(f3_2) * int64(f7_38) + f3f8_38 := int64(f3_2) * int64(f8_19) + f3f9_76 := int64(f3_2) * int64(f9_38) + f4f4 := int64(f4) * int64(f4) + f4f5_2 := int64(f4_2) * int64(f5) + f4f6_38 := int64(f4_2) * int64(f6_19) + f4f7_38 := int64(f4) * int64(f7_38) + f4f8_38 := int64(f4_2) * int64(f8_19) + f4f9_38 := int64(f4) * int64(f9_38) + f5f5_38 := int64(f5) * int64(f5_38) + f5f6_38 := int64(f5_2) * int64(f6_19) + f5f7_76 := int64(f5_2) * int64(f7_38) + f5f8_38 := int64(f5_2) * int64(f8_19) + f5f9_76 := int64(f5_2) * int64(f9_38) + f6f6_19 := int64(f6) * int64(f6_19) + f6f7_38 := int64(f6) * int64(f7_38) + f6f8_38 := int64(f6_2) * int64(f8_19) + f6f9_38 := int64(f6) * int64(f9_38) + f7f7_38 := int64(f7) * int64(f7_38) + f7f8_38 := int64(f7_2) * int64(f8_19) + f7f9_76 := int64(f7_2) * int64(f9_38) + f8f8_19 := int64(f8) * int64(f8_19) + f8f9_38 := int64(f8) * int64(f9_38) + f9f9_38 := int64(f9) * int64(f9_38) + h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38 + h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38 + h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19 + h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38 + h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38 + h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38 + h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19 + h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38 + h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38 + h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2 + var carry [10]int64 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// feSquare2 sets h = 2 * f * f +// +// Can overlap h with f. +// +// Preconditions: +// |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +// See fe_mul.c for discussion of implementation strategy. +func feSquare2(h, f *fieldElement) { + f0 := f[0] + f1 := f[1] + f2 := f[2] + f3 := f[3] + f4 := f[4] + f5 := f[5] + f6 := f[6] + f7 := f[7] + f8 := f[8] + f9 := f[9] + f0_2 := 2 * f0 + f1_2 := 2 * f1 + f2_2 := 2 * f2 + f3_2 := 2 * f3 + f4_2 := 2 * f4 + f5_2 := 2 * f5 + f6_2 := 2 * f6 + f7_2 := 2 * f7 + f5_38 := 38 * f5 // 1.959375*2^30 + f6_19 := 19 * f6 // 1.959375*2^30 + f7_38 := 38 * f7 // 1.959375*2^30 + f8_19 := 19 * f8 // 1.959375*2^30 + f9_38 := 38 * f9 // 1.959375*2^30 + f0f0 := int64(f0) * int64(f0) + f0f1_2 := int64(f0_2) * int64(f1) + f0f2_2 := int64(f0_2) * int64(f2) + f0f3_2 := int64(f0_2) * int64(f3) + f0f4_2 := int64(f0_2) * int64(f4) + f0f5_2 := int64(f0_2) * int64(f5) + f0f6_2 := int64(f0_2) * int64(f6) + f0f7_2 := int64(f0_2) * int64(f7) + f0f8_2 := int64(f0_2) * int64(f8) + f0f9_2 := int64(f0_2) * int64(f9) + f1f1_2 := int64(f1_2) * int64(f1) + f1f2_2 := int64(f1_2) * int64(f2) + f1f3_4 := int64(f1_2) * int64(f3_2) + f1f4_2 := int64(f1_2) * int64(f4) + f1f5_4 := int64(f1_2) * int64(f5_2) + f1f6_2 := int64(f1_2) * int64(f6) + f1f7_4 := int64(f1_2) * int64(f7_2) + f1f8_2 := int64(f1_2) * int64(f8) + f1f9_76 := int64(f1_2) * int64(f9_38) + f2f2 := int64(f2) * int64(f2) + f2f3_2 := int64(f2_2) * int64(f3) + f2f4_2 := int64(f2_2) * int64(f4) + f2f5_2 := int64(f2_2) * int64(f5) + f2f6_2 := int64(f2_2) * int64(f6) + f2f7_2 := int64(f2_2) * int64(f7) + f2f8_38 := int64(f2_2) * int64(f8_19) + f2f9_38 := int64(f2) * int64(f9_38) + f3f3_2 := int64(f3_2) * int64(f3) + f3f4_2 := int64(f3_2) * int64(f4) + f3f5_4 := int64(f3_2) * int64(f5_2) + f3f6_2 := int64(f3_2) * int64(f6) + f3f7_76 := int64(f3_2) * int64(f7_38) + f3f8_38 := int64(f3_2) * int64(f8_19) + f3f9_76 := int64(f3_2) * int64(f9_38) + f4f4 := int64(f4) * int64(f4) + f4f5_2 := int64(f4_2) * int64(f5) + f4f6_38 := int64(f4_2) * int64(f6_19) + f4f7_38 := int64(f4) * int64(f7_38) + f4f8_38 := int64(f4_2) * int64(f8_19) + f4f9_38 := int64(f4) * int64(f9_38) + f5f5_38 := int64(f5) * int64(f5_38) + f5f6_38 := int64(f5_2) * int64(f6_19) + f5f7_76 := int64(f5_2) * int64(f7_38) + f5f8_38 := int64(f5_2) * int64(f8_19) + f5f9_76 := int64(f5_2) * int64(f9_38) + f6f6_19 := int64(f6) * int64(f6_19) + f6f7_38 := int64(f6) * int64(f7_38) + f6f8_38 := int64(f6_2) * int64(f8_19) + f6f9_38 := int64(f6) * int64(f9_38) + f7f7_38 := int64(f7) * int64(f7_38) + f7f8_38 := int64(f7_2) * int64(f8_19) + f7f9_76 := int64(f7_2) * int64(f9_38) + f8f8_19 := int64(f8) * int64(f8_19) + f8f9_38 := int64(f8) * int64(f9_38) + f9f9_38 := int64(f9) * int64(f9_38) + h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38 + h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38 + h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19 + h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38 + h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38 + h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38 + h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19 + h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38 + h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38 + h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2 + var carry [10]int64 + + h0 += h0 + h1 += h1 + h2 += h2 + h3 += h3 + h4 += h4 + h5 += h5 + h6 += h6 + h7 += h7 + h8 += h8 + h9 += h9 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +func feInvert(out, z *fieldElement) { + var t0, t1, t2, t3 fieldElement + var i int + + feSquare(&t0, z) // 2^1 + feSquare(&t1, &t0) // 2^2 + for i = 1; i < 2; i++ { // 2^3 + feSquare(&t1, &t1) + } + feMul(&t1, z, &t1) // 2^3 + 2^0 + feMul(&t0, &t0, &t1) // 2^3 + 2^1 + 2^0 + feSquare(&t2, &t0) // 2^4 + 2^2 + 2^1 + feMul(&t1, &t1, &t2) // 2^4 + 2^3 + 2^2 + 2^1 + 2^0 + feSquare(&t2, &t1) // 5,4,3,2,1 + for i = 1; i < 5; i++ { // 9,8,7,6,5 + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) // 9,8,7,6,5,4,3,2,1,0 + feSquare(&t2, &t1) // 10..1 + for i = 1; i < 10; i++ { // 19..10 + feSquare(&t2, &t2) + } + feMul(&t2, &t2, &t1) // 19..0 + feSquare(&t3, &t2) // 20..1 + for i = 1; i < 20; i++ { // 39..20 + feSquare(&t3, &t3) + } + feMul(&t2, &t3, &t2) // 39..0 + feSquare(&t2, &t2) // 40..1 + for i = 1; i < 10; i++ { // 49..10 + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) // 49..0 + feSquare(&t2, &t1) // 50..1 + for i = 1; i < 50; i++ { // 99..50 + feSquare(&t2, &t2) + } + feMul(&t2, &t2, &t1) // 99..0 + feSquare(&t3, &t2) // 100..1 + for i = 1; i < 100; i++ { // 199..100 + feSquare(&t3, &t3) + } + feMul(&t2, &t3, &t2) // 199..0 + feSquare(&t2, &t2) // 200..1 + for i = 1; i < 50; i++ { // 249..50 + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) // 249..0 + feSquare(&t1, &t1) // 250..1 + for i = 1; i < 5; i++ { // 254..5 + feSquare(&t1, &t1) + } + feMul(out, &t1, &t0) // 254..5,3,1,0 +} + +func fePow22523(out, z *fieldElement) { + var t0, t1, t2 fieldElement + var i int + + feSquare(&t0, z) + for i = 1; i < 1; i++ { + feSquare(&t0, &t0) + } + feSquare(&t1, &t0) + for i = 1; i < 2; i++ { + feSquare(&t1, &t1) + } + feMul(&t1, z, &t1) + feMul(&t0, &t0, &t1) + feSquare(&t0, &t0) + for i = 1; i < 1; i++ { + feSquare(&t0, &t0) + } + feMul(&t0, &t1, &t0) + feSquare(&t1, &t0) + for i = 1; i < 5; i++ { + feSquare(&t1, &t1) + } + feMul(&t0, &t1, &t0) + feSquare(&t1, &t0) + for i = 1; i < 10; i++ { + feSquare(&t1, &t1) + } + feMul(&t1, &t1, &t0) + feSquare(&t2, &t1) + for i = 1; i < 20; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) + feSquare(&t1, &t1) + for i = 1; i < 10; i++ { + feSquare(&t1, &t1) + } + feMul(&t0, &t1, &t0) + feSquare(&t1, &t0) + for i = 1; i < 50; i++ { + feSquare(&t1, &t1) + } + feMul(&t1, &t1, &t0) + feSquare(&t2, &t1) + for i = 1; i < 100; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) + feSquare(&t1, &t1) + for i = 1; i < 50; i++ { + feSquare(&t1, &t1) + } + feMul(&t0, &t1, &t0) + feSquare(&t0, &t0) + for i = 1; i < 2; i++ { + feSquare(&t0, &t0) + } + feMul(out, &t0, z) +} + +func (fe *fieldElement) String() string { + s := "fieldElement{" + for i := range fe { + if i > 0 { + s += ", " + } + s += fmt.Sprintf("%d", fe[i]) + } + s += "}" + return s +} diff --git a/ocs/edwards25519/ge.go b/ocs/edwards25519/ge.go new file mode 100644 index 0000000000..1e0d11ada2 --- /dev/null +++ b/ocs/edwards25519/ge.go @@ -0,0 +1,489 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package edwards25519 + +// Group elements are members of the elliptic curve -x^2 + y^2 = 1 + d * x^2 * +// y^2 where d = -121665/121666. +// +// Several representations are used: +// projectiveGroupElement: (X:Y:Z) satisfying x=X/Z, y=Y/Z +// extendedGroupElement: (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT +// completedGroupElement: ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T +// preComputedGroupElement: (y+x,y-x,2dxy) + +type projectiveGroupElement struct { + X, Y, Z fieldElement +} + +type extendedGroupElement struct { + X, Y, Z, T fieldElement +} + +type completedGroupElement struct { + X, Y, Z, T fieldElement +} + +type preComputedGroupElement struct { + yPlusX, yMinusX, xy2d fieldElement +} + +type cachedGroupElement struct { + yPlusX, yMinusX, Z, T2d fieldElement +} + +func (p *projectiveGroupElement) Zero() { + feZero(&p.X) + feOne(&p.Y) + feOne(&p.Z) +} + +func (p *projectiveGroupElement) Double(r *completedGroupElement) { + var t0 fieldElement + + feSquare(&r.X, &p.X) + feSquare(&r.Z, &p.Y) + feSquare2(&r.T, &p.Z) + feAdd(&r.Y, &p.X, &p.Y) + feSquare(&t0, &r.Y) + feAdd(&r.Y, &r.Z, &r.X) + feSub(&r.Z, &r.Z, &r.X) + feSub(&r.X, &t0, &r.Y) + feSub(&r.T, &r.T, &r.Z) +} + +func (p *projectiveGroupElement) ToBytes(s *[32]byte) { + var recip, x, y fieldElement + + feInvert(&recip, &p.Z) + feMul(&x, &p.X, &recip) + feMul(&y, &p.Y, &recip) + feToBytes(s, &y) + s[31] ^= feIsNegative(&x) << 7 +} + +func (p *extendedGroupElement) Zero() { + feZero(&p.X) + feOne(&p.Y) + feOne(&p.Z) + feZero(&p.T) +} + +func (p *extendedGroupElement) Neg(s *extendedGroupElement) { + feNeg(&p.X, &s.X) + feCopy(&p.Y, &s.Y) + feCopy(&p.Z, &s.Z) + feNeg(&p.T, &s.T) +} + +func (p *extendedGroupElement) Double(r *completedGroupElement) { + var q projectiveGroupElement + p.ToProjective(&q) + q.Double(r) +} + +func (p *extendedGroupElement) ToCached(r *cachedGroupElement) { + feAdd(&r.yPlusX, &p.Y, &p.X) + feSub(&r.yMinusX, &p.Y, &p.X) + feCopy(&r.Z, &p.Z) + feMul(&r.T2d, &p.T, &d2) +} + +func (p *extendedGroupElement) ToProjective(r *projectiveGroupElement) { + feCopy(&r.X, &p.X) + feCopy(&r.Y, &p.Y) + feCopy(&r.Z, &p.Z) +} + +func (p *extendedGroupElement) ToBytes(s *[32]byte) { + var recip, x, y fieldElement + + feInvert(&recip, &p.Z) + feMul(&x, &p.X, &recip) + feMul(&y, &p.Y, &recip) + feToBytes(s, &y) + s[31] ^= feIsNegative(&x) << 7 +} + +func (p *extendedGroupElement) FromBytes(s []byte) bool { + var u, v, v3, vxx, check fieldElement + + if len(s) != 32 { + return false + } + feFromBytes(&p.Y, s) + feOne(&p.Z) + feSquare(&u, &p.Y) + feMul(&v, &u, &d) + feSub(&u, &u, &p.Z) // y = y^2-1 + feAdd(&v, &v, &p.Z) // v = dy^2+1 + + feSquare(&v3, &v) + feMul(&v3, &v3, &v) // v3 = v^3 + feSquare(&p.X, &v3) + feMul(&p.X, &p.X, &v) + feMul(&p.X, &p.X, &u) // x = uv^7 + + fePow22523(&p.X, &p.X) // x = (uv^7)^((q-5)/8) + feMul(&p.X, &p.X, &v3) + feMul(&p.X, &p.X, &u) // x = uv^3(uv^7)^((q-5)/8) + + feSquare(&vxx, &p.X) + feMul(&vxx, &vxx, &v) + feSub(&check, &vxx, &u) // vx^2-u + if feIsNonZero(&check) == 1 { + feAdd(&check, &vxx, &u) // vx^2+u + if feIsNonZero(&check) == 1 { + return false + } + feMul(&p.X, &p.X, &sqrtM1) + } + + if feIsNegative(&p.X) != (s[31] >> 7) { + feNeg(&p.X, &p.X) + } + + feMul(&p.T, &p.X, &p.Y) + return true +} + +func (p *extendedGroupElement) String() string { + return "extendedGroupElement{\n\t" + + p.X.String() + ",\n\t" + + p.Y.String() + ",\n\t" + + p.Z.String() + ",\n\t" + + p.T.String() + ",\n}" +} + +// completedGroupElement methods + +func (c *completedGroupElement) ToProjective(r *projectiveGroupElement) { + feMul(&r.X, &c.X, &c.T) + feMul(&r.Y, &c.Y, &c.Z) + feMul(&r.Z, &c.Z, &c.T) +} + +func (c *completedGroupElement) ToExtended(r *extendedGroupElement) { + feMul(&r.X, &c.X, &c.T) + feMul(&r.Y, &c.Y, &c.Z) + feMul(&r.Z, &c.Z, &c.T) + feMul(&r.T, &c.X, &c.Y) +} + +func (p *preComputedGroupElement) Zero() { + feOne(&p.yPlusX) + feOne(&p.yMinusX) + feZero(&p.xy2d) +} + +func (c *completedGroupElement) Add(p *extendedGroupElement, q *cachedGroupElement) { + var t0 fieldElement + + feAdd(&c.X, &p.Y, &p.X) + feSub(&c.Y, &p.Y, &p.X) + feMul(&c.Z, &c.X, &q.yPlusX) + feMul(&c.Y, &c.Y, &q.yMinusX) + feMul(&c.T, &q.T2d, &p.T) + feMul(&c.X, &p.Z, &q.Z) + feAdd(&t0, &c.X, &c.X) + feSub(&c.X, &c.Z, &c.Y) + feAdd(&c.Y, &c.Z, &c.Y) + feAdd(&c.Z, &t0, &c.T) + feSub(&c.T, &t0, &c.T) +} + +func (c *completedGroupElement) Sub(p *extendedGroupElement, q *cachedGroupElement) { + var t0 fieldElement + + feAdd(&c.X, &p.Y, &p.X) + feSub(&c.Y, &p.Y, &p.X) + feMul(&c.Z, &c.X, &q.yMinusX) + feMul(&c.Y, &c.Y, &q.yPlusX) + feMul(&c.T, &q.T2d, &p.T) + feMul(&c.X, &p.Z, &q.Z) + feAdd(&t0, &c.X, &c.X) + feSub(&c.X, &c.Z, &c.Y) + feAdd(&c.Y, &c.Z, &c.Y) + feSub(&c.Z, &t0, &c.T) + feAdd(&c.T, &t0, &c.T) +} + +func (c *completedGroupElement) MixedAdd(p *extendedGroupElement, q *preComputedGroupElement) { + var t0 fieldElement + + feAdd(&c.X, &p.Y, &p.X) + feSub(&c.Y, &p.Y, &p.X) + feMul(&c.Z, &c.X, &q.yPlusX) + feMul(&c.Y, &c.Y, &q.yMinusX) + feMul(&c.T, &q.xy2d, &p.T) + feAdd(&t0, &p.Z, &p.Z) + feSub(&c.X, &c.Z, &c.Y) + feAdd(&c.Y, &c.Z, &c.Y) + feAdd(&c.Z, &t0, &c.T) + feSub(&c.T, &t0, &c.T) +} + +func (c *completedGroupElement) MixedSub(p *extendedGroupElement, q *preComputedGroupElement) { + var t0 fieldElement + + feAdd(&c.X, &p.Y, &p.X) + feSub(&c.Y, &p.Y, &p.X) + feMul(&c.Z, &c.X, &q.yMinusX) + feMul(&c.Y, &c.Y, &q.yPlusX) + feMul(&c.T, &q.xy2d, &p.T) + feAdd(&t0, &p.Z, &p.Z) + feSub(&c.X, &c.Z, &c.Y) + feAdd(&c.Y, &c.Z, &c.Y) + feSub(&c.Z, &t0, &c.T) + feAdd(&c.T, &t0, &c.T) +} + +// preComputedGroupElement methods + +// Set to u conditionally based on b +func (p *preComputedGroupElement) CMove(u *preComputedGroupElement, b int32) { + feCMove(&p.yPlusX, &u.yPlusX, b) + feCMove(&p.yMinusX, &u.yMinusX, b) + feCMove(&p.xy2d, &u.xy2d, b) +} + +// Set to negative of t +func (p *preComputedGroupElement) Neg(t *preComputedGroupElement) { + feCopy(&p.yPlusX, &t.yMinusX) + feCopy(&p.yMinusX, &t.yPlusX) + feNeg(&p.xy2d, &t.xy2d) +} + +// cachedGroupElement methods + +func (r *cachedGroupElement) Zero() { + feOne(&r.yPlusX) + feOne(&r.yMinusX) + feOne(&r.Z) + feZero(&r.T2d) +} + +// Set to u conditionally based on b +func (r *cachedGroupElement) CMove(u *cachedGroupElement, b int32) { + feCMove(&r.yPlusX, &u.yPlusX, b) + feCMove(&r.yMinusX, &u.yMinusX, b) + feCMove(&r.Z, &u.Z, b) + feCMove(&r.T2d, &u.T2d, b) +} + +// Set to negative of t +func (r *cachedGroupElement) Neg(t *cachedGroupElement) { + feCopy(&r.yPlusX, &t.yMinusX) + feCopy(&r.yMinusX, &t.yPlusX) + feCopy(&r.Z, &t.Z) + feNeg(&r.T2d, &t.T2d) +} + +// Expand the 32-byte (256-bit) exponent in slice a into +// a sequence of 256 multipliers, one per exponent bit position. +// Clumps nearby 1 bits into multi-bit multipliers to reduce +// the total number of add/sub operations in a Point multiply; +// each multiplier is either zero or an odd number between -15 and 15. +// Assumes the target array r has been preinitialized with zeros +// in case the input slice a is less than 32 bytes. +func slide(r *[256]int8, a *[32]byte) { + + // Explode the exponent a into a little-endian array, one bit per byte + for i := range a { + ai := int8(a[i]) + for j := 0; j < 8; j++ { + r[i*8+j] = ai & 1 + ai >>= 1 + } + } + + // Go through and clump sequences of 1-bits together wherever possible, + // while keeping r[i] in the range -15 through 15. + // Note that each nonzero r[i] in the result will always be odd, + // because clumping is triggered by the first, least-significant, + // 1-bit encountered in a clump, and that first bit always remains 1. + for i := range r { + if r[i] != 0 { + for b := 1; b <= 6 && i+b < 256; b++ { + if r[i+b] != 0 { + if r[i]+(r[i+b]<= -15 { + r[i] -= r[i+b] << uint(b) + for k := i + b; k < 256; k++ { + if r[k] == 0 { + r[k] = 1 + break + } + r[k] = 0 + } + } else { + break + } + } + } + } + } +} + +// equal returns 1 if b == c and 0 otherwise. +func equal(b, c int32) int32 { + x := uint32(b ^ c) + x-- + return int32(x >> 31) +} + +// negative returns 1 if b < 0 and 0 otherwise. +func negative(b int32) int32 { + return (b >> 31) & 1 +} + +func selectPreComputed(t *preComputedGroupElement, pos int32, b int32) { + var minusT preComputedGroupElement + bNegative := negative(b) + bAbs := b - (((-bNegative) & b) << 1) + + t.Zero() + for i := int32(0); i < 8; i++ { + t.CMove(&base[pos][i], equal(bAbs, i+1)) + } + minusT.Neg(t) + t.CMove(&minusT, bNegative) +} + +// geScalarMultBase computes h = a*B, where +// a = a[0]+256*a[1]+...+256^31 a[31] +// B is the Ed25519 base Point (x,4/5) with x positive. +// +// Preconditions: +// a[31] <= 127 +func geScalarMultBase(h *extendedGroupElement, a *[32]byte) { + var e [64]int8 + + for i, v := range a { + e[2*i] = int8(v & 15) + e[2*i+1] = int8((v >> 4) & 15) + } + + // each e[i] is between 0 and 15 and e[63] is between 0 and 7. + + carry := int8(0) + for i := 0; i < 63; i++ { + e[i] += carry + carry = (e[i] + 8) >> 4 + e[i] -= carry << 4 + } + e[63] += carry + // each e[i] is between -8 and 8. + + h.Zero() + var t preComputedGroupElement + var r completedGroupElement + for i := int32(1); i < 64; i += 2 { + selectPreComputed(&t, i/2, int32(e[i])) + r.MixedAdd(h, &t) + r.ToExtended(h) + } + + var s projectiveGroupElement + + h.Double(&r) + r.ToProjective(&s) + s.Double(&r) + r.ToProjective(&s) + s.Double(&r) + r.ToProjective(&s) + s.Double(&r) + r.ToExtended(h) + + for i := int32(0); i < 64; i += 2 { + selectPreComputed(&t, i/2, int32(e[i])) + r.MixedAdd(h, &t) + r.ToExtended(h) + } +} + +func selectCached(c *cachedGroupElement, Ai *[8]cachedGroupElement, b int32) { + bNegative := negative(b) + bAbs := b - (((-bNegative) & b) << 1) + + // in constant-time pick cached multiplier for exponent 0 through 8 + c.Zero() + for i := int32(0); i < 8; i++ { + c.CMove(&Ai[i], equal(bAbs, i+1)) + } + + // in constant-time compute negated version, conditionally use it + var minusC cachedGroupElement + minusC.Neg(c) + c.CMove(&minusC, bNegative) +} + +// geScalarMult computes h = a*B, where +// a = a[0]+256*a[1]+...+256^31 a[31] +// B is the Ed25519 base Point (x,4/5) with x positive. +// +// Preconditions: +// a[31] <= 127 +func geScalarMult(h *extendedGroupElement, a *[32]byte, + A *extendedGroupElement) { + + var t completedGroupElement + var u extendedGroupElement + var r projectiveGroupElement + var c cachedGroupElement + var i int + + // Break the exponent into 4-bit nybbles. + var e [64]int8 + for i, v := range a { + e[2*i] = int8(v & 15) + e[2*i+1] = int8((v >> 4) & 15) + } + // each e[i] is between 0 and 15 and e[63] is between 0 and 7. + + carry := int8(0) + for i := 0; i < 63; i++ { + e[i] += carry + carry = (e[i] + 8) >> 4 + e[i] -= carry << 4 + } + e[63] += carry + // each e[i] is between -8 and 8. + + // compute cached array of multiples of A from 1A through 8A + var Ai [8]cachedGroupElement // A,1A,2A,3A,4A,5A,6A,7A + A.ToCached(&Ai[0]) + for i := 0; i < 7; i++ { + t.Add(A, &Ai[i]) + t.ToExtended(&u) + u.ToCached(&Ai[i+1]) + } + + // special case for exponent nybble i == 63 + u.Zero() + selectCached(&c, &Ai, int32(e[63])) + t.Add(&u, &c) + + for i = 62; i >= 0; i-- { + + // t <<= 4 + t.ToProjective(&r) + r.Double(&t) + t.ToProjective(&r) + r.Double(&t) + t.ToProjective(&r) + r.Double(&t) + t.ToProjective(&r) + r.Double(&t) + + // Add next nybble + t.ToExtended(&u) + selectCached(&c, &Ai, int32(e[i])) + t.Add(&u, &c) + } + + t.ToExtended(h) +} diff --git a/ocs/edwards25519/ge_mult_vartime.go b/ocs/edwards25519/ge_mult_vartime.go new file mode 100644 index 0000000000..15a7d7248e --- /dev/null +++ b/ocs/edwards25519/ge_mult_vartime.go @@ -0,0 +1,71 @@ +package edwards25519 + +// geScalarMultVartime computes h = a*B, where +// a = a[0]+256*a[1]+...+256^31 a[31] +// B is the Ed25519 base Point (x,4/5) with x positive. +// +// Preconditions: +// a[31] <= 127 +func geScalarMultVartime(h *extendedGroupElement, a *[32]byte, + A *extendedGroupElement) { + + var aSlide [256]int8 + var Ai [8]cachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A + var t completedGroupElement + var u, A2 extendedGroupElement + var r projectiveGroupElement + var i int + + // Slide through the scalar exponent clumping sequences of bits, + // resulting in only zero or odd multipliers between -15 and 15. + slide(&aSlide, a) + + // Form an array of odd multiples of A from 1A through 15A, + // in addition-ready cached group element form. + // We only need odd multiples of A because slide() + // produces only odd-multiple clumps of bits. + A.ToCached(&Ai[0]) + A.Double(&t) + t.ToExtended(&A2) + for i := 0; i < 7; i++ { + t.Add(&A2, &Ai[i]) + t.ToExtended(&u) + u.ToCached(&Ai[i+1]) + } + + // Process the multiplications from most-significant bit downward + for i = 255; ; i-- { + if i < 0 { // no bits set + h.Zero() + return + } + if aSlide[i] != 0 { + break + } + } + + // first (most-significant) nonzero clump of bits + u.Zero() + if aSlide[i] > 0 { + t.Add(&u, &Ai[aSlide[i]/2]) + } else if aSlide[i] < 0 { + t.Sub(&u, &Ai[(-aSlide[i])/2]) + } + i-- + + // remaining bits + for ; i >= 0; i-- { + t.ToProjective(&r) + r.Double(&t) + + if aSlide[i] > 0 { + t.ToExtended(&u) + t.Add(&u, &Ai[aSlide[i]/2]) + } else if aSlide[i] < 0 { + t.ToExtended(&u) + t.Sub(&u, &Ai[(-aSlide[i])/2]) + } + } + + t.ToExtended(h) +} diff --git a/ocs/edwards25519/marshal.go b/ocs/edwards25519/marshal.go new file mode 100644 index 0000000000..573f47529b --- /dev/null +++ b/ocs/edwards25519/marshal.go @@ -0,0 +1,83 @@ +// Package marshalling provides a common implementation of (un)marshalling method using Writer and Reader. +// +package edwards25519 + +import ( + "crypto/cipher" + "io" + "reflect" + + "go.dedis.ch/kyber/v3" +) + +// PointMarshalTo provides a generic implementation of Point.EncodeTo +// based on Point.Encode. +func PointMarshalTo(p kyber.Point, w io.Writer) (int, error) { + buf, err := p.MarshalBinary() + if err != nil { + return 0, err + } + return w.Write(buf) +} + +// PointUnmarshalFrom provides a generic implementation of Point.DecodeFrom, +// based on Point.Decode, or Point.Pick if r is a Cipher or cipher.Stream. +// The returned byte-count is valid only when decoding from a normal Reader, +// not when picking from a pseudorandom source. +func PointUnmarshalFrom(p kyber.Point, r io.Reader) (int, error) { + if strm, ok := r.(cipher.Stream); ok { + p.Pick(strm) + return -1, nil // no byte-count when picking randomly + } + buf := make([]byte, p.MarshalSize()) + n, err := io.ReadFull(r, buf) + if err != nil { + return n, err + } + return n, p.UnmarshalBinary(buf) +} + +// ScalarMarshalTo provides a generic implementation of Scalar.EncodeTo +// based on Scalar.Encode. +func ScalarMarshalTo(s kyber.Scalar, w io.Writer) (int, error) { + buf, err := s.MarshalBinary() + if err != nil { + return 0, err + } + return w.Write(buf) +} + +// ScalarUnmarshalFrom provides a generic implementation of Scalar.DecodeFrom, +// based on Scalar.Decode, or Scalar.Pick if r is a Cipher or cipher.Stream. +// The returned byte-count is valid only when decoding from a normal Reader, +// not when picking from a pseudorandom source. +func ScalarUnmarshalFrom(s kyber.Scalar, r io.Reader) (int, error) { + if strm, ok := r.(cipher.Stream); ok { + s.Pick(strm) + return -1, nil // no byte-count when picking randomly + } + buf := make([]byte, s.MarshalSize()) + n, err := io.ReadFull(r, buf) + if err != nil { + return n, err + } + return n, s.UnmarshalBinary(buf) +} + +// Not used other than for reflect.TypeOf() +var aScalar kyber.Scalar +var aPoint kyber.Point + +var tScalar = reflect.TypeOf(&aScalar).Elem() +var tPoint = reflect.TypeOf(&aPoint).Elem() + +// GroupNew is the Default implementation of reflective constructor for Group +func GroupNew(g kyber.Group, t reflect.Type) interface{} { + switch t { + case tScalar: + return g.Scalar() + case tPoint: + return g.Point() + } + return nil +} diff --git a/ocs/edwards25519/point.go b/ocs/edwards25519/point.go new file mode 100644 index 0000000000..f64a6467db --- /dev/null +++ b/ocs/edwards25519/point.go @@ -0,0 +1,252 @@ +// Package edwards25519 provides an optimized Go implementation of a +// Twisted Edwards curve that is isomorphic to Curve25519. For details see: +// http://ed25519.cr.yp.to/. +// +// This code is based on Adam Langley's Go port of the public domain, +// "ref10" implementation of the ed25519 signing scheme in C from SUPERCOP. +// It was generalized and extended to support full kyber.Group arithmetic +// by the DEDIS lab at Yale and EPFL. +// +// Due to the field element and group arithmetic optimizations +// described in the Ed25519 paper, this implementation generally +// performs extremely well, typically comparable to native C +// implementations. The tradeoff is that this code is completely +// specialized to a single curve. +package edwards25519 + +import ( + "crypto/cipher" + "encoding/hex" + "errors" + "io" + + "go.dedis.ch/kyber/v3" +) + +var marshalPointID = [8]byte{'e', 'd', '.', 'p', 'o', 'i', 'n', 't'} + +type Point struct { + ge extendedGroupElement + varTime bool +} + +func (P *Point) String() string { + var b [32]byte + P.ge.ToBytes(&b) + return hex.EncodeToString(b[:]) +} + +func (P *Point) Norm() ([]byte, []byte) { + var recip, x, y fieldElement + + feInvert(&recip, &P.ge.Z) + feMul(&x, &P.ge.X, &recip) + feMul(&y, &P.ge.Y, &recip) + var sx, sy [32]byte + feToBytes(&sx, &x) + feToBytes(&sy, &y) + return sx[:], sy[:] +} + +func (P *Point) X_LE() []byte { + x, _ := P.Norm() + return x +} + +func (P *Point) Y_LE() []byte { + _, y := P.Norm() + return y +} + +func (P *Point) MarshalSize() int { + return 32 +} + +func (P *Point) MarshalBinary() ([]byte, error) { + var b [32]byte + P.ge.ToBytes(&b) + return b[:], nil +} + +// MarshalID returns the type tag used in encoding/decoding +func (P *Point) MarshalID() [8]byte { + return marshalPointID +} + +func (P *Point) UnmarshalBinary(b []byte) error { + if !P.ge.FromBytes(b) { + return errors.New("invalid Ed25519 curve Point") + } + return nil +} + +func (P *Point) MarshalTo(w io.Writer) (int, error) { + return PointMarshalTo(P, w) +} + +func (P *Point) UnmarshalFrom(r io.Reader) (int, error) { + return PointUnmarshalFrom(P, r) +} + +// Equality test for two Points on the same curve +func (P *Point) Equal(P2 kyber.Point) bool { + + var b1, b2 [32]byte + P.ge.ToBytes(&b1) + P2.(*Point).ge.ToBytes(&b2) + for i := range b1 { + if b1[i] != b2[i] { + return false + } + } + return true +} + +// Set Point to be equal to P2. +func (P *Point) Set(P2 kyber.Point) kyber.Point { + P.ge = P2.(*Point).ge + return P +} + +// Set Point to be equal to P2. +func (P *Point) Clone() kyber.Point { + return &Point{ge: P.ge} +} + +// Set to the neutral element, which is (0,1) for twisted Edwards curves. +func (P *Point) Null() kyber.Point { + P.ge.Zero() + return P +} + +// Set to the standard base Point for this curve +func (P *Point) Base() kyber.Point { + P.ge = baseext + return P +} + +func (P *Point) EmbedLen() int { + // Reserve the most-significant 8 bits for pseudo-randomness. + // Reserve the least-significant 8 bits for embedded data length. + // (Hopefully it's unlikely we'll need >=2048-bit curves soon.) + return (255 - 8 - 8) / 8 +} + +func (P *Point) Embed(data []byte, rand cipher.Stream) kyber.Point { + + // How many bytes to embed? + dl := P.EmbedLen() + if dl > len(data) { + dl = len(data) + } + + for { + // Pick a random Point, with optional embedded data + var b [32]byte + rand.XORKeyStream(b[:], b[:]) + if data != nil { + b[0] = byte(dl) // Encode length in low 8 bits + copy(b[1:1+dl], data) // Copy in data to embed + } + if !P.ge.FromBytes(b[:]) { // Try to decode + continue // invalid Point, retry + } + + // If we're using the full group, + // we just need any Point on the curve, so we're done. + // if c.full { + // return P,data[dl:] + // } + + // We're using the prime-order subgroup, + // so we need to make sure the Point is in that subencoding. + // If we're not trying to embed data, + // we can convert our Point into one in the subgroup + // simply by multiplying it by the cofactor. + if data == nil { + P.Mul(cofactorScalar, P) // multiply by cofactor + if P.Equal(nullPoint) { + continue // unlucky; try again + } + return P // success + } + + // Since we need the Point's y-coordinate to hold our data, + // we must simply check if the Point is in the subgroup + // and retry Point generation until it is. + var Q Point + Q.Mul(primeOrderScalar, P) + if Q.Equal(nullPoint) { + return P // success + } + // Keep trying... + } +} + +func (P *Point) Pick(rand cipher.Stream) kyber.Point { + return P.Embed(nil, rand) +} + +// Extract embedded data from a Point group element +func (P *Point) Data() ([]byte, error) { + var b [32]byte + P.ge.ToBytes(&b) + dl := int(b[0]) // extract length byte + if dl > P.EmbedLen() { + return nil, errors.New("invalid embedded data length") + } + return b[1 : 1+dl], nil +} + +func (P *Point) Add(P1, P2 kyber.Point) kyber.Point { + E1 := P1.(*Point) + E2 := P2.(*Point) + + var t2 cachedGroupElement + var r completedGroupElement + + E2.ge.ToCached(&t2) + r.Add(&E1.ge, &t2) + r.ToExtended(&P.ge) + + return P +} + +func (P *Point) Sub(P1, P2 kyber.Point) kyber.Point { + E1 := P1.(*Point) + E2 := P2.(*Point) + + var t2 cachedGroupElement + var r completedGroupElement + + E2.ge.ToCached(&t2) + r.Sub(&E1.ge, &t2) + r.ToExtended(&P.ge) + + return P +} + +// Neg finds the negative of Point A. +// For Edwards curves, the negative of (x,y) is (-x,y). +func (P *Point) Neg(A kyber.Point) kyber.Point { + P.ge.Neg(&A.(*Point).ge) + return P +} + +// Mul multiplies Point p by scalar s using the repeated doubling method. +func (P *Point) Mul(s kyber.Scalar, A kyber.Point) kyber.Point { + + a := &s.(*scalar).v + + if A == nil { + geScalarMultBase(&P.ge, a) + } else { + if P.varTime { + geScalarMultVartime(&P.ge, a, &A.(*Point).ge) + } else { + geScalarMult(&P.ge, a, &A.(*Point).ge) + } + } + + return P +} diff --git a/ocs/edwards25519/point_test.go b/ocs/edwards25519/point_test.go new file mode 100644 index 0000000000..3be5b8f1f0 --- /dev/null +++ b/ocs/edwards25519/point_test.go @@ -0,0 +1,13 @@ +package edwards25519 + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestPoint_Marshal(t *testing.T) { + p := Point{} + require.Equal(t, "ed.Point", fmt.Sprintf("%s", p.MarshalID())) +} diff --git a/ocs/edwards25519/point_vartime.go b/ocs/edwards25519/point_vartime.go new file mode 100644 index 0000000000..2c3f2af76d --- /dev/null +++ b/ocs/edwards25519/point_vartime.go @@ -0,0 +1,9 @@ +package edwards25519 + +// AllowVarTime sets a flag in this object which determines if a faster +// but variable time implementation can be used. Set this only on Points +// which represent public information. Using variable time algorithms to +// operate on private information can result in timing side-channels. +func (P *Point) AllowVarTime(varTime bool) { + P.varTime = varTime +} diff --git a/ocs/edwards25519/scalar.go b/ocs/edwards25519/scalar.go new file mode 100644 index 0000000000..45949dd712 --- /dev/null +++ b/ocs/edwards25519/scalar.go @@ -0,0 +1,2231 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package edwards25519 + +import ( + "crypto/cipher" + "crypto/subtle" + "encoding/hex" + "errors" + "io" + "math/big" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/mod" + "go.dedis.ch/kyber/v3/util/random" +) + +// This code is a port of the public domain, "ref10" implementation of ed25519 +// from SUPERCOP. More information at https://bench.cr.yp.to/supercop.html. + +// The scalars are GF(2^252 + 27742317777372353535851937790883648493). + +var marshalScalarID = [8]byte{'e', 'd', '.', 's', 'c', 'a', 'l', 'a'} + +type scalar struct { + v [32]byte +} + +// Equality test for two Scalars derived from the same Group +func (s *scalar) Equal(s2 kyber.Scalar) bool { + v1 := s.v[:] + v2 := s2.(*scalar).v[:] + return subtle.ConstantTimeCompare(v1, v2) != 0 +} + +// Set equal to another Scalar a +func (s *scalar) Set(a kyber.Scalar) kyber.Scalar { + s.v = a.(*scalar).v + return s +} + +// Clone returns a duplicate of the scalar s. +func (s *scalar) Clone() kyber.Scalar { + s2 := *s + return &s2 +} + +func (s *scalar) setInt(i *mod.Int) kyber.Scalar { + b := i.LittleEndian(32, 32) + copy(s.v[:], b) + return s +} + +// SetInt64 sets the scalar to a small integer value. +func (s *scalar) SetInt64(v int64) kyber.Scalar { + return s.setInt(mod.NewInt64(v, primeOrder)) +} + +func (s *scalar) toInt() *mod.Int { + return mod.NewIntBytes(s.v[:], primeOrder, mod.LittleEndian) +} + +// Set to the additive identity (0) +func (s *scalar) Zero() kyber.Scalar { + s.v = [32]byte{0} + return s +} + +// Set to the multiplicative identity (1) +func (s *scalar) One() kyber.Scalar { + s.v = [32]byte{1} + return s +} + +// Set to the modular sum of scalars a and b +func (s *scalar) Add(a, b kyber.Scalar) kyber.Scalar { + scAdd(&s.v, &a.(*scalar).v, &b.(*scalar).v) + return s +} + +// Set to the modular difference a - b +func (s *scalar) Sub(a, b kyber.Scalar) kyber.Scalar { + scSub(&s.v, &a.(*scalar).v, &b.(*scalar).v) + return s +} + +// Set to the modular negation of scalar a +func (s *scalar) Neg(a kyber.Scalar) kyber.Scalar { + var z scalar + z.Zero() + scSub(&s.v, &z.v, &a.(*scalar).v) + return s +} + +// Set to the modular product of scalars a and b +func (s *scalar) Mul(a, b kyber.Scalar) kyber.Scalar { + scMul(&s.v, &a.(*scalar).v, &b.(*scalar).v) + return s +} + +// Set to the modular division of scalar a by scalar b +func (s *scalar) Div(a, b kyber.Scalar) kyber.Scalar { + var i scalar + i.Inv(b) + scMul(&s.v, &a.(*scalar).v, &i.v) + return s +} + +// Set to the modular inverse of scalar a +func (s *scalar) Inv(a kyber.Scalar) kyber.Scalar { + var res scalar + res.One() + ac := a.(*scalar) + // Modular inversion in a multiplicative group is a^(phi(m)-1) = a^-1 mod m + // Since m is prime, phi(m) = m - 1 => a^(m-2) = a^-1 mod m. + // The inverse is computed using the exponentation-and-square algorithm. + // Implementation is constant time regarding the value a, it only depends on + // the modulo. + for i := 255; i >= 0; i-- { + bit := lMinus2.Bit(i) + // square step + scMul(&res.v, &res.v, &res.v) + if bit == 1 { + // multiply step + scMul(&res.v, &res.v, &ac.v) + } + } + s.v = res.v + return s +} + +// Set to a fresh random or pseudo-random scalar +func (s *scalar) Pick(rand cipher.Stream) kyber.Scalar { + i := mod.NewInt(random.Int(primeOrder, rand), primeOrder) + return s.setInt(i) +} + +// SetBytes s to b, interpreted as a little endian integer. +func (s *scalar) SetBytes(b []byte) kyber.Scalar { + return s.setInt(mod.NewIntBytes(b, primeOrder, mod.LittleEndian)) +} + +// String returns the string representation of this scalar (fixed length of 32 bytes, little endian). +func (s *scalar) String() string { + b, _ := s.toInt().MarshalBinary() + for len(b) < 32 { + b = append(b, 0) + } + return hex.EncodeToString(b) +} + +// Encoded length of this object in bytes. +func (s *scalar) MarshalSize() int { + return 32 +} + +// MarshalBinary returns the binary representation of this scalar. +func (s *scalar) MarshalBinary() ([]byte, error) { + return s.toInt().MarshalBinary() +} + +// MarshalID returns the type tag used in encoding/decoding +func (s *scalar) MarshalID() [8]byte { + return marshalScalarID +} + +// UnmarshalBinary reads the binary representation of a scalar. +func (s *scalar) UnmarshalBinary(buf []byte) error { + if len(buf) != 32 { + return errors.New("wrong size buffer") + } + copy(s.v[:], buf) + return nil +} + +// MarshalTo writes the binary representation of this scalar to the given +// writer. +func (s *scalar) MarshalTo(w io.Writer) (int, error) { + return ScalarMarshalTo(s, w) +} + +// UnmarshalFrom reads the binary representation of a scalar from the given +// reader. +func (s *scalar) UnmarshalFrom(r io.Reader) (int, error) { + return ScalarUnmarshalFrom(s, r) +} + +func newScalarInt(i *big.Int) *scalar { + s := scalar{} + s.setInt(mod.NewInt(i, fullOrder)) + return &s +} + +// Input: +// a[0]+256*a[1]+...+256^31*a[31] = a +// b[0]+256*b[1]+...+256^31*b[31] = b +// c[0]+256*c[1]+...+256^31*c[31] = c +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +func scMulAdd(s, a, b, c *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + b0 := 2097151 & load3(b[:]) + b1 := 2097151 & (load4(b[2:]) >> 5) + b2 := 2097151 & (load3(b[5:]) >> 2) + b3 := 2097151 & (load4(b[7:]) >> 7) + b4 := 2097151 & (load4(b[10:]) >> 4) + b5 := 2097151 & (load3(b[13:]) >> 1) + b6 := 2097151 & (load4(b[15:]) >> 6) + b7 := 2097151 & (load3(b[18:]) >> 3) + b8 := 2097151 & load3(b[21:]) + b9 := 2097151 & (load4(b[23:]) >> 5) + b10 := 2097151 & (load3(b[26:]) >> 2) + b11 := (load4(b[28:]) >> 7) + c0 := 2097151 & load3(c[:]) + c1 := 2097151 & (load4(c[2:]) >> 5) + c2 := 2097151 & (load3(c[5:]) >> 2) + c3 := 2097151 & (load4(c[7:]) >> 7) + c4 := 2097151 & (load4(c[10:]) >> 4) + c5 := 2097151 & (load3(c[13:]) >> 1) + c6 := 2097151 & (load4(c[15:]) >> 6) + c7 := 2097151 & (load3(c[18:]) >> 3) + c8 := 2097151 & load3(c[21:]) + c9 := 2097151 & (load4(c[23:]) >> 5) + c10 := 2097151 & (load3(c[26:]) >> 2) + c11 := (load4(c[28:]) >> 7) + var carry [23]int64 + + s0 := c0 + a0*b0 + s1 := c1 + a0*b1 + a1*b0 + s2 := c2 + a0*b2 + a1*b1 + a2*b0 + s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 + s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 + s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 + s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 + s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 + s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 + s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 + s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 + s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 + s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 + s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 + s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 + s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 + s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5 + s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6 + s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7 + s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8 + s20 := a9*b11 + a10*b10 + a11*b9 + s21 := a10*b11 + a11*b10 + s22 := a11 * b11 + s23 := int64(0) + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + carry[18] = (s18 + (1 << 20)) >> 21 + s19 += carry[18] + s18 -= carry[18] << 21 + carry[20] = (s20 + (1 << 20)) >> 21 + s21 += carry[20] + s20 -= carry[20] << 21 + carry[22] = (s22 + (1 << 20)) >> 21 + s23 += carry[22] + s22 -= carry[22] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + carry[17] = (s17 + (1 << 20)) >> 21 + s18 += carry[17] + s17 -= carry[17] << 21 + carry[19] = (s19 + (1 << 20)) >> 21 + s20 += carry[19] + s19 -= carry[19] << 21 + carry[21] = (s21 + (1 << 20)) >> 21 + s22 += carry[21] + s21 -= carry[21] << 21 + + s11 += s23 * 666643 + s12 += s23 * 470296 + s13 += s23 * 654183 + s14 -= s23 * 997805 + s15 += s23 * 136657 + s16 -= s23 * 683901 + s23 = 0 + + s10 += s22 * 666643 + s11 += s22 * 470296 + s12 += s22 * 654183 + s13 -= s22 * 997805 + s14 += s22 * 136657 + s15 -= s22 * 683901 + s22 = 0 + + s9 += s21 * 666643 + s10 += s21 * 470296 + s11 += s21 * 654183 + s12 -= s21 * 997805 + s13 += s21 * 136657 + s14 -= s21 * 683901 + s21 = 0 + + s8 += s20 * 666643 + s9 += s20 * 470296 + s10 += s20 * 654183 + s11 -= s20 * 997805 + s12 += s20 * 136657 + s13 -= s20 * 683901 + s20 = 0 + + s7 += s19 * 666643 + s8 += s19 * 470296 + s9 += s19 * 654183 + s10 -= s19 * 997805 + s11 += s19 * 136657 + s12 -= s19 * 683901 + s19 = 0 + + s6 += s18 * 666643 + s7 += s18 * 470296 + s8 += s18 * 654183 + s9 -= s18 * 997805 + s10 += s18 * 136657 + s11 -= s18 * 683901 + s18 = 0 + + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + + s5 += s17 * 666643 + s6 += s17 * 470296 + s7 += s17 * 654183 + s8 -= s17 * 997805 + s9 += s17 * 136657 + s10 -= s17 * 683901 + s17 = 0 + + s4 += s16 * 666643 + s5 += s16 * 470296 + s6 += s16 * 654183 + s7 -= s16 * 997805 + s8 += s16 * 136657 + s9 -= s16 * 683901 + s16 = 0 + + s3 += s15 * 666643 + s4 += s15 * 470296 + s5 += s15 * 654183 + s6 -= s15 * 997805 + s7 += s15 * 136657 + s8 -= s15 * 683901 + s15 = 0 + + s2 += s14 * 666643 + s3 += s14 * 470296 + s4 += s14 * 654183 + s5 -= s14 * 997805 + s6 += s14 * 136657 + s7 -= s14 * 683901 + s14 = 0 + + s1 += s13 * 666643 + s2 += s13 * 470296 + s3 += s13 * 654183 + s4 -= s13 * 997805 + s5 += s13 * 136657 + s6 -= s13 * 683901 + s13 = 0 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[11] = s11 >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + s[0] = byte(s0 >> 0) + s[1] = byte(s0 >> 8) + s[2] = byte((s0 >> 16) | (s1 << 5)) + s[3] = byte(s1 >> 3) + s[4] = byte(s1 >> 11) + s[5] = byte((s1 >> 19) | (s2 << 2)) + s[6] = byte(s2 >> 6) + s[7] = byte((s2 >> 14) | (s3 << 7)) + s[8] = byte(s3 >> 1) + s[9] = byte(s3 >> 9) + s[10] = byte((s3 >> 17) | (s4 << 4)) + s[11] = byte(s4 >> 4) + s[12] = byte(s4 >> 12) + s[13] = byte((s4 >> 20) | (s5 << 1)) + s[14] = byte(s5 >> 7) + s[15] = byte((s5 >> 15) | (s6 << 6)) + s[16] = byte(s6 >> 2) + s[17] = byte(s6 >> 10) + s[18] = byte((s6 >> 18) | (s7 << 3)) + s[19] = byte(s7 >> 5) + s[20] = byte(s7 >> 13) + s[21] = byte(s8 >> 0) + s[22] = byte(s8 >> 8) + s[23] = byte((s8 >> 16) | (s9 << 5)) + s[24] = byte(s9 >> 3) + s[25] = byte(s9 >> 11) + s[26] = byte((s9 >> 19) | (s10 << 2)) + s[27] = byte(s10 >> 6) + s[28] = byte((s10 >> 14) | (s11 << 7)) + s[29] = byte(s11 >> 1) + s[30] = byte(s11 >> 9) + s[31] = byte(s11 >> 17) +} + +// Hacky scAdd cobbled together rather sub-optimally from scMulAdd. +// +// Input: +// a[0]+256*a[1]+...+256^31*a[31] = a +// c[0]+256*c[1]+...+256^31*c[31] = c +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = (a+c) mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +// +func scAdd(s, a, c *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + c0 := 2097151 & load3(c[:]) + c1 := 2097151 & (load4(c[2:]) >> 5) + c2 := 2097151 & (load3(c[5:]) >> 2) + c3 := 2097151 & (load4(c[7:]) >> 7) + c4 := 2097151 & (load4(c[10:]) >> 4) + c5 := 2097151 & (load3(c[13:]) >> 1) + c6 := 2097151 & (load4(c[15:]) >> 6) + c7 := 2097151 & (load3(c[18:]) >> 3) + c8 := 2097151 & load3(c[21:]) + c9 := 2097151 & (load4(c[23:]) >> 5) + c10 := 2097151 & (load3(c[26:]) >> 2) + c11 := (load4(c[28:]) >> 7) + var carry [23]int64 + + s0 := c0 + a0 + s1 := c1 + a1 + s2 := c2 + a2 + s3 := c3 + a3 + s4 := c4 + a4 + s5 := c5 + a5 + s6 := c6 + a6 + s7 := c7 + a7 + s8 := c8 + a8 + s9 := c9 + a9 + s10 := c10 + a10 + s11 := c11 + a11 + s12 := int64(0) + s13 := int64(0) + s14 := int64(0) + s15 := int64(0) + s16 := int64(0) + s17 := int64(0) + s18 := int64(0) + s19 := int64(0) + s20 := int64(0) + s21 := int64(0) + s22 := int64(0) + s23 := int64(0) + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + carry[18] = (s18 + (1 << 20)) >> 21 + s19 += carry[18] + s18 -= carry[18] << 21 + carry[20] = (s20 + (1 << 20)) >> 21 + s21 += carry[20] + s20 -= carry[20] << 21 + carry[22] = (s22 + (1 << 20)) >> 21 + s23 += carry[22] + s22 -= carry[22] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + carry[17] = (s17 + (1 << 20)) >> 21 + s18 += carry[17] + s17 -= carry[17] << 21 + carry[19] = (s19 + (1 << 20)) >> 21 + s20 += carry[19] + s19 -= carry[19] << 21 + carry[21] = (s21 + (1 << 20)) >> 21 + s22 += carry[21] + s21 -= carry[21] << 21 + + s11 += s23 * 666643 + s12 += s23 * 470296 + s13 += s23 * 654183 + s14 -= s23 * 997805 + s15 += s23 * 136657 + s16 -= s23 * 683901 + s23 = 0 + + s10 += s22 * 666643 + s11 += s22 * 470296 + s12 += s22 * 654183 + s13 -= s22 * 997805 + s14 += s22 * 136657 + s15 -= s22 * 683901 + s22 = 0 + + s9 += s21 * 666643 + s10 += s21 * 470296 + s11 += s21 * 654183 + s12 -= s21 * 997805 + s13 += s21 * 136657 + s14 -= s21 * 683901 + s21 = 0 + + s8 += s20 * 666643 + s9 += s20 * 470296 + s10 += s20 * 654183 + s11 -= s20 * 997805 + s12 += s20 * 136657 + s13 -= s20 * 683901 + s20 = 0 + + s7 += s19 * 666643 + s8 += s19 * 470296 + s9 += s19 * 654183 + s10 -= s19 * 997805 + s11 += s19 * 136657 + s12 -= s19 * 683901 + s19 = 0 + + s6 += s18 * 666643 + s7 += s18 * 470296 + s8 += s18 * 654183 + s9 -= s18 * 997805 + s10 += s18 * 136657 + s11 -= s18 * 683901 + s18 = 0 + + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + + s5 += s17 * 666643 + s6 += s17 * 470296 + s7 += s17 * 654183 + s8 -= s17 * 997805 + s9 += s17 * 136657 + s10 -= s17 * 683901 + s17 = 0 + + s4 += s16 * 666643 + s5 += s16 * 470296 + s6 += s16 * 654183 + s7 -= s16 * 997805 + s8 += s16 * 136657 + s9 -= s16 * 683901 + s16 = 0 + + s3 += s15 * 666643 + s4 += s15 * 470296 + s5 += s15 * 654183 + s6 -= s15 * 997805 + s7 += s15 * 136657 + s8 -= s15 * 683901 + s15 = 0 + + s2 += s14 * 666643 + s3 += s14 * 470296 + s4 += s14 * 654183 + s5 -= s14 * 997805 + s6 += s14 * 136657 + s7 -= s14 * 683901 + s14 = 0 + + s1 += s13 * 666643 + s2 += s13 * 470296 + s3 += s13 * 654183 + s4 -= s13 * 997805 + s5 += s13 * 136657 + s6 -= s13 * 683901 + s13 = 0 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[11] = s11 >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + s[0] = byte(s0 >> 0) + s[1] = byte(s0 >> 8) + s[2] = byte((s0 >> 16) | (s1 << 5)) + s[3] = byte(s1 >> 3) + s[4] = byte(s1 >> 11) + s[5] = byte((s1 >> 19) | (s2 << 2)) + s[6] = byte(s2 >> 6) + s[7] = byte((s2 >> 14) | (s3 << 7)) + s[8] = byte(s3 >> 1) + s[9] = byte(s3 >> 9) + s[10] = byte((s3 >> 17) | (s4 << 4)) + s[11] = byte(s4 >> 4) + s[12] = byte(s4 >> 12) + s[13] = byte((s4 >> 20) | (s5 << 1)) + s[14] = byte(s5 >> 7) + s[15] = byte((s5 >> 15) | (s6 << 6)) + s[16] = byte(s6 >> 2) + s[17] = byte(s6 >> 10) + s[18] = byte((s6 >> 18) | (s7 << 3)) + s[19] = byte(s7 >> 5) + s[20] = byte(s7 >> 13) + s[21] = byte(s8 >> 0) + s[22] = byte(s8 >> 8) + s[23] = byte((s8 >> 16) | (s9 << 5)) + s[24] = byte(s9 >> 3) + s[25] = byte(s9 >> 11) + s[26] = byte((s9 >> 19) | (s10 << 2)) + s[27] = byte(s10 >> 6) + s[28] = byte((s10 >> 14) | (s11 << 7)) + s[29] = byte(s11 >> 1) + s[30] = byte(s11 >> 9) + s[31] = byte(s11 >> 17) +} + +// Hacky scSub cobbled together rather sub-optimally from scMulAdd. +// +// Input: +// a[0]+256*a[1]+...+256^31*a[31] = a +// c[0]+256*c[1]+...+256^31*c[31] = c +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = (a-c) mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +// +func scSub(s, a, c *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + c0 := 2097151 & load3(c[:]) + c1 := 2097151 & (load4(c[2:]) >> 5) + c2 := 2097151 & (load3(c[5:]) >> 2) + c3 := 2097151 & (load4(c[7:]) >> 7) + c4 := 2097151 & (load4(c[10:]) >> 4) + c5 := 2097151 & (load3(c[13:]) >> 1) + c6 := 2097151 & (load4(c[15:]) >> 6) + c7 := 2097151 & (load3(c[18:]) >> 3) + c8 := 2097151 & load3(c[21:]) + c9 := 2097151 & (load4(c[23:]) >> 5) + c10 := 2097151 & (load3(c[26:]) >> 2) + c11 := (load4(c[28:]) >> 7) + var carry [23]int64 + + s0 := 1916624 - c0 + a0 + s1 := 863866 - c1 + a1 + s2 := 18828 - c2 + a2 + s3 := 1284811 - c3 + a3 + s4 := 2007799 - c4 + a4 + s5 := 456654 - c5 + a5 + s6 := 5 - c6 + a6 + s7 := 0 - c7 + a7 + s8 := 0 - c8 + a8 + s9 := 0 - c9 + a9 + s10 := 0 - c10 + a10 + s11 := 0 - c11 + a11 + s12 := int64(16) + s13 := int64(0) + s14 := int64(0) + s15 := int64(0) + s16 := int64(0) + s17 := int64(0) + s18 := int64(0) + s19 := int64(0) + s20 := int64(0) + s21 := int64(0) + s22 := int64(0) + s23 := int64(0) + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + carry[18] = (s18 + (1 << 20)) >> 21 + s19 += carry[18] + s18 -= carry[18] << 21 + carry[20] = (s20 + (1 << 20)) >> 21 + s21 += carry[20] + s20 -= carry[20] << 21 + carry[22] = (s22 + (1 << 20)) >> 21 + s23 += carry[22] + s22 -= carry[22] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + carry[17] = (s17 + (1 << 20)) >> 21 + s18 += carry[17] + s17 -= carry[17] << 21 + carry[19] = (s19 + (1 << 20)) >> 21 + s20 += carry[19] + s19 -= carry[19] << 21 + carry[21] = (s21 + (1 << 20)) >> 21 + s22 += carry[21] + s21 -= carry[21] << 21 + + s11 += s23 * 666643 + s12 += s23 * 470296 + s13 += s23 * 654183 + s14 -= s23 * 997805 + s15 += s23 * 136657 + s16 -= s23 * 683901 + s23 = 0 + + s10 += s22 * 666643 + s11 += s22 * 470296 + s12 += s22 * 654183 + s13 -= s22 * 997805 + s14 += s22 * 136657 + s15 -= s22 * 683901 + s22 = 0 + + s9 += s21 * 666643 + s10 += s21 * 470296 + s11 += s21 * 654183 + s12 -= s21 * 997805 + s13 += s21 * 136657 + s14 -= s21 * 683901 + s21 = 0 + + s8 += s20 * 666643 + s9 += s20 * 470296 + s10 += s20 * 654183 + s11 -= s20 * 997805 + s12 += s20 * 136657 + s13 -= s20 * 683901 + s20 = 0 + + s7 += s19 * 666643 + s8 += s19 * 470296 + s9 += s19 * 654183 + s10 -= s19 * 997805 + s11 += s19 * 136657 + s12 -= s19 * 683901 + s19 = 0 + + s6 += s18 * 666643 + s7 += s18 * 470296 + s8 += s18 * 654183 + s9 -= s18 * 997805 + s10 += s18 * 136657 + s11 -= s18 * 683901 + s18 = 0 + + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + + s5 += s17 * 666643 + s6 += s17 * 470296 + s7 += s17 * 654183 + s8 -= s17 * 997805 + s9 += s17 * 136657 + s10 -= s17 * 683901 + s17 = 0 + + s4 += s16 * 666643 + s5 += s16 * 470296 + s6 += s16 * 654183 + s7 -= s16 * 997805 + s8 += s16 * 136657 + s9 -= s16 * 683901 + s16 = 0 + + s3 += s15 * 666643 + s4 += s15 * 470296 + s5 += s15 * 654183 + s6 -= s15 * 997805 + s7 += s15 * 136657 + s8 -= s15 * 683901 + s15 = 0 + + s2 += s14 * 666643 + s3 += s14 * 470296 + s4 += s14 * 654183 + s5 -= s14 * 997805 + s6 += s14 * 136657 + s7 -= s14 * 683901 + s14 = 0 + + s1 += s13 * 666643 + s2 += s13 * 470296 + s3 += s13 * 654183 + s4 -= s13 * 997805 + s5 += s13 * 136657 + s6 -= s13 * 683901 + s13 = 0 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[11] = s11 >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + s[0] = byte(s0 >> 0) + s[1] = byte(s0 >> 8) + s[2] = byte((s0 >> 16) | (s1 << 5)) + s[3] = byte(s1 >> 3) + s[4] = byte(s1 >> 11) + s[5] = byte((s1 >> 19) | (s2 << 2)) + s[6] = byte(s2 >> 6) + s[7] = byte((s2 >> 14) | (s3 << 7)) + s[8] = byte(s3 >> 1) + s[9] = byte(s3 >> 9) + s[10] = byte((s3 >> 17) | (s4 << 4)) + s[11] = byte(s4 >> 4) + s[12] = byte(s4 >> 12) + s[13] = byte((s4 >> 20) | (s5 << 1)) + s[14] = byte(s5 >> 7) + s[15] = byte((s5 >> 15) | (s6 << 6)) + s[16] = byte(s6 >> 2) + s[17] = byte(s6 >> 10) + s[18] = byte((s6 >> 18) | (s7 << 3)) + s[19] = byte(s7 >> 5) + s[20] = byte(s7 >> 13) + s[21] = byte(s8 >> 0) + s[22] = byte(s8 >> 8) + s[23] = byte((s8 >> 16) | (s9 << 5)) + s[24] = byte(s9 >> 3) + s[25] = byte(s9 >> 11) + s[26] = byte((s9 >> 19) | (s10 << 2)) + s[27] = byte(s10 >> 6) + s[28] = byte((s10 >> 14) | (s11 << 7)) + s[29] = byte(s11 >> 1) + s[30] = byte(s11 >> 9) + s[31] = byte(s11 >> 17) +} + +// Hacky scMul cobbled together rather sub-optimally from scMulAdd. +// +// Input: +// a[0]+256*a[1]+...+256^31*a[31] = a +// b[0]+256*b[1]+...+256^31*b[31] = b +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = (ab) mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +func scMul(s, a, b *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + b0 := 2097151 & load3(b[:]) + b1 := 2097151 & (load4(b[2:]) >> 5) + b2 := 2097151 & (load3(b[5:]) >> 2) + b3 := 2097151 & (load4(b[7:]) >> 7) + b4 := 2097151 & (load4(b[10:]) >> 4) + b5 := 2097151 & (load3(b[13:]) >> 1) + b6 := 2097151 & (load4(b[15:]) >> 6) + b7 := 2097151 & (load3(b[18:]) >> 3) + b8 := 2097151 & load3(b[21:]) + b9 := 2097151 & (load4(b[23:]) >> 5) + b10 := 2097151 & (load3(b[26:]) >> 2) + b11 := (load4(b[28:]) >> 7) + c0 := int64(0) + c1 := int64(0) + c2 := int64(0) + c3 := int64(0) + c4 := int64(0) + c5 := int64(0) + c6 := int64(0) + c7 := int64(0) + c8 := int64(0) + c9 := int64(0) + c10 := int64(0) + c11 := int64(0) + var carry [23]int64 + + s0 := c0 + a0*b0 + s1 := c1 + a0*b1 + a1*b0 + s2 := c2 + a0*b2 + a1*b1 + a2*b0 + s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 + s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 + s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 + s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 + s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 + s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 + s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 + s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 + s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 + s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 + s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 + s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 + s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 + s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5 + s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6 + s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7 + s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8 + s20 := a9*b11 + a10*b10 + a11*b9 + s21 := a10*b11 + a11*b10 + s22 := a11 * b11 + s23 := int64(0) + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + carry[18] = (s18 + (1 << 20)) >> 21 + s19 += carry[18] + s18 -= carry[18] << 21 + carry[20] = (s20 + (1 << 20)) >> 21 + s21 += carry[20] + s20 -= carry[20] << 21 + carry[22] = (s22 + (1 << 20)) >> 21 + s23 += carry[22] + s22 -= carry[22] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + carry[17] = (s17 + (1 << 20)) >> 21 + s18 += carry[17] + s17 -= carry[17] << 21 + carry[19] = (s19 + (1 << 20)) >> 21 + s20 += carry[19] + s19 -= carry[19] << 21 + carry[21] = (s21 + (1 << 20)) >> 21 + s22 += carry[21] + s21 -= carry[21] << 21 + + s11 += s23 * 666643 + s12 += s23 * 470296 + s13 += s23 * 654183 + s14 -= s23 * 997805 + s15 += s23 * 136657 + s16 -= s23 * 683901 + s23 = 0 + + s10 += s22 * 666643 + s11 += s22 * 470296 + s12 += s22 * 654183 + s13 -= s22 * 997805 + s14 += s22 * 136657 + s15 -= s22 * 683901 + s22 = 0 + + s9 += s21 * 666643 + s10 += s21 * 470296 + s11 += s21 * 654183 + s12 -= s21 * 997805 + s13 += s21 * 136657 + s14 -= s21 * 683901 + s21 = 0 + + s8 += s20 * 666643 + s9 += s20 * 470296 + s10 += s20 * 654183 + s11 -= s20 * 997805 + s12 += s20 * 136657 + s13 -= s20 * 683901 + s20 = 0 + + s7 += s19 * 666643 + s8 += s19 * 470296 + s9 += s19 * 654183 + s10 -= s19 * 997805 + s11 += s19 * 136657 + s12 -= s19 * 683901 + s19 = 0 + + s6 += s18 * 666643 + s7 += s18 * 470296 + s8 += s18 * 654183 + s9 -= s18 * 997805 + s10 += s18 * 136657 + s11 -= s18 * 683901 + s18 = 0 + + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + + s5 += s17 * 666643 + s6 += s17 * 470296 + s7 += s17 * 654183 + s8 -= s17 * 997805 + s9 += s17 * 136657 + s10 -= s17 * 683901 + s17 = 0 + + s4 += s16 * 666643 + s5 += s16 * 470296 + s6 += s16 * 654183 + s7 -= s16 * 997805 + s8 += s16 * 136657 + s9 -= s16 * 683901 + s16 = 0 + + s3 += s15 * 666643 + s4 += s15 * 470296 + s5 += s15 * 654183 + s6 -= s15 * 997805 + s7 += s15 * 136657 + s8 -= s15 * 683901 + s15 = 0 + + s2 += s14 * 666643 + s3 += s14 * 470296 + s4 += s14 * 654183 + s5 -= s14 * 997805 + s6 += s14 * 136657 + s7 -= s14 * 683901 + s14 = 0 + + s1 += s13 * 666643 + s2 += s13 * 470296 + s3 += s13 * 654183 + s4 -= s13 * 997805 + s5 += s13 * 136657 + s6 -= s13 * 683901 + s13 = 0 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[11] = s11 >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + s[0] = byte(s0 >> 0) + s[1] = byte(s0 >> 8) + s[2] = byte((s0 >> 16) | (s1 << 5)) + s[3] = byte(s1 >> 3) + s[4] = byte(s1 >> 11) + s[5] = byte((s1 >> 19) | (s2 << 2)) + s[6] = byte(s2 >> 6) + s[7] = byte((s2 >> 14) | (s3 << 7)) + s[8] = byte(s3 >> 1) + s[9] = byte(s3 >> 9) + s[10] = byte((s3 >> 17) | (s4 << 4)) + s[11] = byte(s4 >> 4) + s[12] = byte(s4 >> 12) + s[13] = byte((s4 >> 20) | (s5 << 1)) + s[14] = byte(s5 >> 7) + s[15] = byte((s5 >> 15) | (s6 << 6)) + s[16] = byte(s6 >> 2) + s[17] = byte(s6 >> 10) + s[18] = byte((s6 >> 18) | (s7 << 3)) + s[19] = byte(s7 >> 5) + s[20] = byte(s7 >> 13) + s[21] = byte(s8 >> 0) + s[22] = byte(s8 >> 8) + s[23] = byte((s8 >> 16) | (s9 << 5)) + s[24] = byte(s9 >> 3) + s[25] = byte(s9 >> 11) + s[26] = byte((s9 >> 19) | (s10 << 2)) + s[27] = byte(s10 >> 6) + s[28] = byte((s10 >> 14) | (s11 << 7)) + s[29] = byte(s11 >> 1) + s[30] = byte(s11 >> 9) + s[31] = byte(s11 >> 17) +} + +// Input: +// s[0]+256*s[1]+...+256^63*s[63] = s +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = s mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +func scReduce(out *[32]byte, s *[64]byte) { + s0 := 2097151 & load3(s[:]) + s1 := 2097151 & (load4(s[2:]) >> 5) + s2 := 2097151 & (load3(s[5:]) >> 2) + s3 := 2097151 & (load4(s[7:]) >> 7) + s4 := 2097151 & (load4(s[10:]) >> 4) + s5 := 2097151 & (load3(s[13:]) >> 1) + s6 := 2097151 & (load4(s[15:]) >> 6) + s7 := 2097151 & (load3(s[18:]) >> 3) + s8 := 2097151 & load3(s[21:]) + s9 := 2097151 & (load4(s[23:]) >> 5) + s10 := 2097151 & (load3(s[26:]) >> 2) + s11 := 2097151 & (load4(s[28:]) >> 7) + s12 := 2097151 & (load4(s[31:]) >> 4) + s13 := 2097151 & (load3(s[34:]) >> 1) + s14 := 2097151 & (load4(s[36:]) >> 6) + s15 := 2097151 & (load3(s[39:]) >> 3) + s16 := 2097151 & load3(s[42:]) + s17 := 2097151 & (load4(s[44:]) >> 5) + s18 := 2097151 & (load3(s[47:]) >> 2) + s19 := 2097151 & (load4(s[49:]) >> 7) + s20 := 2097151 & (load4(s[52:]) >> 4) + s21 := 2097151 & (load3(s[55:]) >> 1) + s22 := 2097151 & (load4(s[57:]) >> 6) + s23 := (load4(s[60:]) >> 3) + + s11 += s23 * 666643 + s12 += s23 * 470296 + s13 += s23 * 654183 + s14 -= s23 * 997805 + s15 += s23 * 136657 + s16 -= s23 * 683901 + s23 = 0 + + s10 += s22 * 666643 + s11 += s22 * 470296 + s12 += s22 * 654183 + s13 -= s22 * 997805 + s14 += s22 * 136657 + s15 -= s22 * 683901 + s22 = 0 + + s9 += s21 * 666643 + s10 += s21 * 470296 + s11 += s21 * 654183 + s12 -= s21 * 997805 + s13 += s21 * 136657 + s14 -= s21 * 683901 + s21 = 0 + + s8 += s20 * 666643 + s9 += s20 * 470296 + s10 += s20 * 654183 + s11 -= s20 * 997805 + s12 += s20 * 136657 + s13 -= s20 * 683901 + s20 = 0 + + s7 += s19 * 666643 + s8 += s19 * 470296 + s9 += s19 * 654183 + s10 -= s19 * 997805 + s11 += s19 * 136657 + s12 -= s19 * 683901 + s19 = 0 + + s6 += s18 * 666643 + s7 += s18 * 470296 + s8 += s18 * 654183 + s9 -= s18 * 997805 + s10 += s18 * 136657 + s11 -= s18 * 683901 + s18 = 0 + + var carry [17]int64 + + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + + s5 += s17 * 666643 + s6 += s17 * 470296 + s7 += s17 * 654183 + s8 -= s17 * 997805 + s9 += s17 * 136657 + s10 -= s17 * 683901 + s17 = 0 + + s4 += s16 * 666643 + s5 += s16 * 470296 + s6 += s16 * 654183 + s7 -= s16 * 997805 + s8 += s16 * 136657 + s9 -= s16 * 683901 + s16 = 0 + + s3 += s15 * 666643 + s4 += s15 * 470296 + s5 += s15 * 654183 + s6 -= s15 * 997805 + s7 += s15 * 136657 + s8 -= s15 * 683901 + s15 = 0 + + s2 += s14 * 666643 + s3 += s14 * 470296 + s4 += s14 * 654183 + s5 -= s14 * 997805 + s6 += s14 * 136657 + s7 -= s14 * 683901 + s14 = 0 + + s1 += s13 * 666643 + s2 += s13 * 470296 + s3 += s13 * 654183 + s4 -= s13 * 997805 + s5 += s13 * 136657 + s6 -= s13 * 683901 + s13 = 0 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[11] = s11 >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + out[0] = byte(s0 >> 0) + out[1] = byte(s0 >> 8) + out[2] = byte((s0 >> 16) | (s1 << 5)) + out[3] = byte(s1 >> 3) + out[4] = byte(s1 >> 11) + out[5] = byte((s1 >> 19) | (s2 << 2)) + out[6] = byte(s2 >> 6) + out[7] = byte((s2 >> 14) | (s3 << 7)) + out[8] = byte(s3 >> 1) + out[9] = byte(s3 >> 9) + out[10] = byte((s3 >> 17) | (s4 << 4)) + out[11] = byte(s4 >> 4) + out[12] = byte(s4 >> 12) + out[13] = byte((s4 >> 20) | (s5 << 1)) + out[14] = byte(s5 >> 7) + out[15] = byte((s5 >> 15) | (s6 << 6)) + out[16] = byte(s6 >> 2) + out[17] = byte(s6 >> 10) + out[18] = byte((s6 >> 18) | (s7 << 3)) + out[19] = byte(s7 >> 5) + out[20] = byte(s7 >> 13) + out[21] = byte(s8 >> 0) + out[22] = byte(s8 >> 8) + out[23] = byte((s8 >> 16) | (s9 << 5)) + out[24] = byte(s9 >> 3) + out[25] = byte(s9 >> 11) + out[26] = byte((s9 >> 19) | (s10 << 2)) + out[27] = byte(s10 >> 6) + out[28] = byte((s10 >> 14) | (s11 << 7)) + out[29] = byte(s11 >> 1) + out[30] = byte(s11 >> 9) + out[31] = byte(s11 >> 17) +} diff --git a/ocs/edwards25519/scalar_test.go b/ocs/edwards25519/scalar_test.go new file mode 100644 index 0000000000..0e8459c9a1 --- /dev/null +++ b/ocs/edwards25519/scalar_test.go @@ -0,0 +1,459 @@ +package edwards25519 + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/util/random" +) + +// SimpleCTScalar implements the scalar operations only using `ScMulAdd` by +// playing with the parameters. +type SimpleCTScalar struct { + *scalar +} + +func newSimpleCTScalar() kyber.Scalar { + return &SimpleCTScalar{&scalar{}} +} + +var one = new(scalar).SetInt64(1).(*scalar) +var zero = new(scalar).Zero().(*scalar) + +var minusOne = new(scalar).SetBytes([]byte{0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}).(*scalar) + +func (s *SimpleCTScalar) Add(s1, s2 kyber.Scalar) kyber.Scalar { + sc1 := s1.(*SimpleCTScalar) + sc2 := s2.(*SimpleCTScalar) + + // a * b + c = a * 1 + c + scMulAdd(&s.v, &sc1.v, &one.v, &sc2.v) + return s +} + +func (s *SimpleCTScalar) Mul(s1, s2 kyber.Scalar) kyber.Scalar { + sc1 := s1.(*SimpleCTScalar) + sc2 := s2.(*SimpleCTScalar) + + // a * b + c = a * b + 0 + scMulAdd(&s.v, &sc1.v, &sc2.v, &zero.v) + return s +} + +func (s *SimpleCTScalar) Sub(s1, s2 kyber.Scalar) kyber.Scalar { + sc1 := s1.(*SimpleCTScalar) + sc2 := s2.(*SimpleCTScalar) + + // a * b + c = -1 * a + c + scMulAdd(&s.v, &minusOne.v, &sc1.v, &sc2.v) + return s + +} + +func (s *SimpleCTScalar) Equal(s2 kyber.Scalar) bool { + return s.scalar.Equal(s2.(*SimpleCTScalar).scalar) +} + +// factoredScalar implements the scalar operations using a factored version or +// `ScReduce` at the end of each operations. +type factoredScalar struct { + *scalar +} + +func newFactoredScalar() kyber.Scalar { + return &factoredScalar{&scalar{}} +} + +func (s *factoredScalar) Add(s1, s2 kyber.Scalar) kyber.Scalar { + sf1 := s1.(*factoredScalar) + sf2 := s2.(*factoredScalar) + scAddFact(&s.v, &sf1.v, &sf2.v) + return s +} + +func (s *factoredScalar) Mul(s1, s2 kyber.Scalar) kyber.Scalar { + sf1 := s1.(*factoredScalar) + sf2 := s2.(*factoredScalar) + scMulFact(&s.v, &sf1.v, &sf2.v) + return s +} + +func (s *factoredScalar) Sub(s1, s2 kyber.Scalar) kyber.Scalar { + sf1 := s1.(*factoredScalar) + sf2 := s2.(*factoredScalar) + scSubFact(&s.v, &sf1.v, &sf2.v) + return s +} + +func (s *factoredScalar) Equal(s2 kyber.Scalar) bool { + return s.scalar.Equal(s2.(*factoredScalar).scalar) +} + +func TestFactoredScalar(t *testing.T) { + testSimple(t, newFactoredScalar) +} + +func TestSimpleCTScalar(t *testing.T) { + testSimple(t, newSimpleCTScalar) +} + +func TestString(t *testing.T) { + // Create a scalar that would trigger #262. + s := new(scalar) + s.SetInt64(0x100) + s.Add(s, one) + if s.String() != "0101000000000000000000000000000000000000000000000000000000000000" { + t.Fatal("unexpected result from String():", s.String()) + } +} + +func TestScalar_Marshal(t *testing.T) { + s := &scalar{} + require.Equal(t, "ed.scala", fmt.Sprintf("%s", s.MarshalID())) +} + +func TestSetBytesLE(t *testing.T) { + s := new(scalar) + s.SetBytes([]byte{0, 1, 2, 3}) + if s.String() != "0001020300000000000000000000000000000000000000000000000000000000" { + t.Fatal("unexpected result from String():", s.String()) + } +} + +func testSimple(t *testing.T, new func() kyber.Scalar) { + s1 := new() + s2 := new() + s3 := new() + s1.SetInt64(2) + s2.Pick(random.New()) + + s22 := new().Add(s2, s2) + + if !s3.Mul(s1, s2).Equal(s22) { + t.Fail() + } + +} + +func benchScalarAdd(b *testing.B, new func() kyber.Scalar) { + var seed = tSuite.XOF([]byte("hello world")) + s1 := new() + s2 := new() + s3 := new() + s1.Pick(seed) + s2.Pick(seed) + + for i := 0; i < b.N; i++ { + s3.Add(s1, s2) + } +} + +func benchScalarMul(b *testing.B, new func() kyber.Scalar) { + var seed = tSuite.XOF([]byte("hello world")) + s1 := new() + s2 := new() + s3 := new() + s1.Pick(seed) + s2.Pick(seed) + + for i := 0; i < b.N; i++ { + s3.Mul(s1, s2) + } +} + +func benchScalarSub(b *testing.B, new func() kyber.Scalar) { + var seed = tSuite.XOF([]byte("hello world")) + s1 := new() + s2 := new() + s3 := new() + s1.Pick(seed) + s2.Pick(seed) + + for i := 0; i < b.N; i++ { + s3.Sub(s1, s2) + } +} + +// addition + +func BenchmarkCTScalarAdd(b *testing.B) { benchScalarAdd(b, tSuite.Scalar) } + +func BenchmarkCTScalarSimpleAdd(b *testing.B) { benchScalarAdd(b, newSimpleCTScalar) } + +func BenchmarkCTScalarFactoredAdd(b *testing.B) { benchScalarAdd(b, newFactoredScalar) } + +// multiplication + +func BenchmarkCTScalarMul(b *testing.B) { benchScalarMul(b, tSuite.Scalar) } + +func BenchmarkCTScalarSimpleMul(b *testing.B) { benchScalarMul(b, newSimpleCTScalar) } + +func BenchmarkCTScalarFactoredMul(b *testing.B) { benchScalarMul(b, newFactoredScalar) } + +// substraction + +func BenchmarkCTScalarSub(b *testing.B) { benchScalarSub(b, tSuite.Scalar) } + +func BenchmarkCTScalarSimpleSub(b *testing.B) { benchScalarSub(b, newSimpleCTScalar) } + +func BenchmarkCTScalarFactoredSub(b *testing.B) { benchScalarSub(b, newFactoredScalar) } + +func doCarryUncentered(limbs [24]int64, i int) { + carry := limbs[i] >> 21 + limbs[i+1] += carry + limbs[i] -= carry << 21 +} + +// Carry excess from the `i`-th limb into the `(i+1)`-th limb. +// Postcondition: `-2^20 <= limbs[i] < 2^20`. +func doCarryCentered(limbs [24]int64, i int) { + carry := (limbs[i] + (1 << 20)) >> 21 + limbs[i+1] += carry + limbs[i] -= carry << 21 +} + +func doReduction(limbs [24]int64, i int) { + limbs[i-12] += limbs[i] * 666643 + limbs[i-11] += limbs[i] * 470296 + limbs[i-10] += limbs[i] * 654183 + limbs[i-9] -= limbs[i] * 997805 + limbs[i-8] += limbs[i] * 136657 + limbs[i-7] -= limbs[i] * 683901 + limbs[i] = 0 +} + +func scReduceLimbs(limbs [24]int64) { + //for i in 0..23 { + for i := 0; i < 23; i++ { + doCarryCentered(limbs, i) + } + //for i in (0..23).filter(|x| x % 2 == 1) { + for i := 1; i < 23; i += 2 { + doCarryCentered(limbs, i) + } + + doReduction(limbs, 23) + doReduction(limbs, 22) + doReduction(limbs, 21) + doReduction(limbs, 20) + doReduction(limbs, 19) + doReduction(limbs, 18) + + //for i in (6..18).filter(|x| x % 2 == 0) { + for i := 6; i < 18; i += 2 { + doCarryCentered(limbs, i) + } + + // for i in (6..16).filter(|x| x % 2 == 1) { + for i := 7; i < 16; i += 2 { + doCarryCentered(limbs, i) + } + doReduction(limbs, 17) + doReduction(limbs, 16) + doReduction(limbs, 15) + doReduction(limbs, 14) + doReduction(limbs, 13) + doReduction(limbs, 12) + + //for i in (0..12).filter(|x| x % 2 == 0) { + for i := 0; i < 12; i += 2 { + doCarryCentered(limbs, i) + } + //for i in (0..12).filter(|x| x % 2 == 1) { + for i := 1; i < 12; i += 2 { + doCarryCentered(limbs, i) + } + + doReduction(limbs, 12) + + //for i in 0..12 { + for i := 0; i < 12; i++ { + doCarryUncentered(limbs, i) + } + + doReduction(limbs, 12) + + //for i in 0..11 { + for i := 0; i < 11; i++ { + doCarryUncentered(limbs, i) + } +} + +func scAddFact(s, a, c *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + c0 := 2097151 & load3(c[:]) + c1 := 2097151 & (load4(c[2:]) >> 5) + c2 := 2097151 & (load3(c[5:]) >> 2) + c3 := 2097151 & (load4(c[7:]) >> 7) + c4 := 2097151 & (load4(c[10:]) >> 4) + c5 := 2097151 & (load3(c[13:]) >> 1) + c6 := 2097151 & (load4(c[15:]) >> 6) + c7 := 2097151 & (load3(c[18:]) >> 3) + c8 := 2097151 & load3(c[21:]) + c9 := 2097151 & (load4(c[23:]) >> 5) + c10 := 2097151 & (load3(c[26:]) >> 2) + c11 := (load4(c[28:]) >> 7) + + var limbs [24]int64 + limbs[0] = c0 + a0 + limbs[1] = c1 + a1 + limbs[2] = c2 + a2 + limbs[3] = c3 + a3 + limbs[4] = c4 + a4 + limbs[5] = c5 + a5 + limbs[6] = c6 + a6 + limbs[7] = c7 + a7 + limbs[8] = c8 + a8 + limbs[9] = c9 + a9 + limbs[10] = c10 + a10 + limbs[11] = c11 + a11 + limbs[12] = int64(0) + limbs[13] = int64(0) + limbs[14] = int64(0) + limbs[15] = int64(0) + limbs[16] = int64(0) + limbs[17] = int64(0) + limbs[18] = int64(0) + limbs[19] = int64(0) + limbs[20] = int64(0) + limbs[21] = int64(0) + limbs[22] = int64(0) + limbs[23] = int64(0) + + scReduceLimbs(limbs) +} + +func scMulFact(s, a, b *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + b0 := 2097151 & load3(b[:]) + b1 := 2097151 & (load4(b[2:]) >> 5) + b2 := 2097151 & (load3(b[5:]) >> 2) + b3 := 2097151 & (load4(b[7:]) >> 7) + b4 := 2097151 & (load4(b[10:]) >> 4) + b5 := 2097151 & (load3(b[13:]) >> 1) + b6 := 2097151 & (load4(b[15:]) >> 6) + b7 := 2097151 & (load3(b[18:]) >> 3) + b8 := 2097151 & load3(b[21:]) + b9 := 2097151 & (load4(b[23:]) >> 5) + b10 := 2097151 & (load3(b[26:]) >> 2) + b11 := (load4(b[28:]) >> 7) + c0 := int64(0) + c1 := int64(0) + c2 := int64(0) + c3 := int64(0) + c4 := int64(0) + c5 := int64(0) + c6 := int64(0) + c7 := int64(0) + c8 := int64(0) + c9 := int64(0) + c10 := int64(0) + c11 := int64(0) + + var limbs [24]int64 + limbs[0] = c0 + a0*b0 + limbs[1] = c1 + a0*b1 + a1*b0 + limbs[2] = c2 + a0*b2 + a1*b1 + a2*b0 + limbs[3] = c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 + limbs[4] = c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 + limbs[5] = c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 + limbs[6] = c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 + limbs[7] = c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 + limbs[8] = c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 + limbs[9] = c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 + limbs[10] = c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 + limbs[11] = c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 + limbs[12] = a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 + limbs[13] = a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 + limbs[14] = a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 + limbs[15] = a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 + limbs[16] = a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5 + limbs[17] = a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6 + limbs[18] = a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7 + limbs[19] = a8*b11 + a9*b10 + a10*b9 + a11*b8 + limbs[20] = a9*b11 + a10*b10 + a11*b9 + limbs[21] = a10*b11 + a11*b10 + limbs[22] = a11 * b11 + limbs[23] = int64(0) + + scReduceLimbs(limbs) +} + +func scSubFact(s, a, c *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + c0 := 2097151 & load3(c[:]) + c1 := 2097151 & (load4(c[2:]) >> 5) + c2 := 2097151 & (load3(c[5:]) >> 2) + c3 := 2097151 & (load4(c[7:]) >> 7) + c4 := 2097151 & (load4(c[10:]) >> 4) + c5 := 2097151 & (load3(c[13:]) >> 1) + c6 := 2097151 & (load4(c[15:]) >> 6) + c7 := 2097151 & (load3(c[18:]) >> 3) + c8 := 2097151 & load3(c[21:]) + c9 := 2097151 & (load4(c[23:]) >> 5) + c10 := 2097151 & (load3(c[26:]) >> 2) + c11 := (load4(c[28:]) >> 7) + + var limbs [24]int64 + limbs[0] = 1916624 - c0 + a0 + limbs[1] = 863866 - c1 + a1 + limbs[2] = 18828 - c2 + a2 + limbs[3] = 1284811 - c3 + a3 + limbs[4] = 2007799 - c4 + a4 + limbs[5] = 456654 - c5 + a5 + limbs[6] = 5 - c6 + a6 + limbs[7] = 0 - c7 + a7 + limbs[8] = 0 - c8 + a8 + limbs[9] = 0 - c9 + a9 + limbs[10] = 0 - c10 + a10 + limbs[11] = 0 - c11 + a11 + limbs[12] = int64(16) + limbs[13] = int64(0) + limbs[14] = int64(0) + limbs[15] = int64(0) + limbs[16] = int64(0) + limbs[17] = int64(0) + limbs[18] = int64(0) + limbs[19] = int64(0) + limbs[20] = int64(0) + limbs[21] = int64(0) + limbs[22] = int64(0) + limbs[23] = int64(0) + + scReduceLimbs(limbs) +} diff --git a/ocs/edwards25519/suite.go b/ocs/edwards25519/suite.go new file mode 100644 index 0000000000..62e353be67 --- /dev/null +++ b/ocs/edwards25519/suite.go @@ -0,0 +1,70 @@ +package edwards25519 + +import ( + "crypto/cipher" + "crypto/sha256" + "hash" + "io" + "reflect" + + "go.dedis.ch/fixbuf" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/util/random" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +// SuiteEd25519 implements some basic functionalities such as Group, HashFactory, +// and XOFFactory. +type SuiteEd25519 struct { + Curve + r cipher.Stream +} + +// Hash returns a newly instanciated sha256 hash function. +func (s *SuiteEd25519) Hash() hash.Hash { + return sha256.New() +} + +// XOF returns an XOF which is implemented via the Blake2b hash. +func (s *SuiteEd25519) XOF(key []byte) kyber.XOF { + return blake2xb.New(key) +} + +func (s *SuiteEd25519) Read(r io.Reader, objs ...interface{}) error { + return fixbuf.Read(r, s, objs...) +} + +func (s *SuiteEd25519) Write(w io.Writer, objs ...interface{}) error { + return fixbuf.Write(w, objs) +} + +// New implements the kyber.Encoding interface +func (s *SuiteEd25519) New(t reflect.Type) interface{} { + return GroupNew(s, t) +} + +// RandomStream returns a cipher.Stream that returns a key stream +// from crypto/rand. +func (s *SuiteEd25519) RandomStream() cipher.Stream { + if s.r != nil { + return s.r + } + return random.New() +} + +// NewBlakeSHA256Ed25519 returns a cipher suite based on package +// go.dedis.ch/kyber/v3/xof/blake2xb, SHA-256, and the Ed25519 curve. +// It produces cryptographically random numbers via package crypto/rand. +func NewBlakeSHA256Ed25519() *SuiteEd25519 { + suite := new(SuiteEd25519) + return suite +} + +// NewBlakeSHA256Ed25519WithRand returns a cipher suite based on package +// go.dedis.ch/kyber/v3/xof/blake2xb, SHA-256, and the Ed25519 curve. +// It produces cryptographically random numbers via the provided stream r. +func NewBlakeSHA256Ed25519WithRand(r cipher.Stream) *SuiteEd25519 { + suite := new(SuiteEd25519) + suite.r = r + return suite +} From 8525170028160f3664dd2ccf1076bd1265588297 Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Thu, 9 May 2019 16:32:21 +0200 Subject: [PATCH 19/21] moved samples out of main() --- ocs/demo/main.go | 108 ++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 52 deletions(-) diff --git a/ocs/demo/main.go b/ocs/demo/main.go index c314c79fc6..ef4eb76ef0 100644 --- a/ocs/demo/main.go +++ b/ocs/demo/main.go @@ -24,63 +24,12 @@ import ( "go.dedis.ch/onet/v3/log" ) -func bigEndianToDecimal(buf []byte) *big.Int { - bi := &big.Int{} - bi.SetBytes(buf) - return bi -} - -func LEBytesToDecimal(buf []byte) *big.Int { - if len(buf)%2 != 0 { - log.Fatal("can only convert even length slices") - } - for i := 0; i < len(buf)/2; i++ { - buf[i], buf[len(buf)-i-1] = buf[len(buf)-i-1], buf[i] - } - return bigEndianToDecimal(buf) -} - -func printScalar(msg string, s kyber.Scalar) { - buf, err := s.MarshalBinary() - log.ErrFatal(err) - var str []string - str = append(str, fmt.Sprint("Representation of a scalar:")) - str = append(str, fmt.Sprintf("\tLittle-endian: %x", buf)) - str = append(str, fmt.Sprintf("\tDecimal: %s", LEBytesToDecimal(buf).String())) - log.Info(msg, strings.Join(str, "\n")) -} - -func printPoint(msg string, p kyber.Point) { - ped := p.(*edwards25519.Point) - var str []string - str = append(str, fmt.Sprint("Representations of a point:")) - str = append(str, fmt.Sprintf("\tCompressed: %s", ped.String())) - str = append(str, fmt.Sprintf("\tLittle-endian X / Y:\n\t\tX: %x\n\t\tY: %x", ped.X_LE(), ped.Y_LE())) - str = append(str, fmt.Sprintf("\tDecimal X / Y:\n\t\tX: %s\n\t\tY: %s", - LEBytesToDecimal(ped.X_LE()).String(), - LEBytesToDecimal(ped.Y_LE()).String())) - log.Info(msg, strings.Join(str, "\n")) -} - func main() { // Use our own ed25519 suite to be able to print x coordinates: cothority.Suite = edwards25519.NewBlakeSHA256Ed25519() if len(os.Args) < 2 { log.Error("Please give a roster.toml as first parameter") - s := cothority.Suite.Scalar().SetInt64(1) - p := cothority.Suite.Point().Base() - printScalar("* A scalar of '1':", s) - printPoint("* The base point:", p) - printScalar("* A scalar of '2':", s.Add(s, s)) - printPoint("* The base point added to himself:", p.Add(p, p)) - printPoint("* 2 x base:", p.Mul(s, nil)) - var allF0 [32]byte - for i := range allF0 { - allF0[i] = 0xf0 - } - s.SetBytes(allF0[:]) - printScalar("* A reduced all-F0 scalar:", s) - printScalar("* A reduced all-F0 scalar added to itself:", s.Add(s, s)) + printSamples() return } roster, err := lib.ReadRoster(os.Args[1]) @@ -174,3 +123,58 @@ func main() { log.Info("Successfully re-encrypted the key") } + +func printSamples() { + s := cothority.Suite.Scalar().SetInt64(1) + p := cothority.Suite.Point().Base() + printScalar("* A scalar of '1':", s) + printPoint("* The base point:", p) + printScalar("* A scalar of '2':", s.Add(s, s)) + printPoint("* The base point added to himself:", p.Add(p, p)) + printPoint("* 2 x base:", p.Mul(s, nil)) + var allF0 [32]byte + for i := range allF0 { + allF0[i] = 0xf0 + } + s.SetBytes(allF0[:]) + printScalar("* A reduced all-F0 scalar:", s) + printScalar("* A reduced all-F0 scalar added to itself:", s.Add(s, s)) +} + +func bigEndianToDecimal(buf []byte) *big.Int { + bi := &big.Int{} + bi.SetBytes(buf) + return bi +} + +func LEBytesToDecimal(buf []byte) *big.Int { + if len(buf)%2 != 0 { + log.Fatal("can only convert even length slices") + } + for i := 0; i < len(buf)/2; i++ { + buf[i], buf[len(buf)-i-1] = buf[len(buf)-i-1], buf[i] + } + return bigEndianToDecimal(buf) +} + +func printScalar(msg string, s kyber.Scalar) { + buf, err := s.MarshalBinary() + log.ErrFatal(err) + var str []string + str = append(str, fmt.Sprint("Representation of a scalar:")) + str = append(str, fmt.Sprintf("\tLittle-endian: %x", buf)) + str = append(str, fmt.Sprintf("\tDecimal: %s", LEBytesToDecimal(buf).String())) + log.Info(msg, strings.Join(str, "\n")) +} + +func printPoint(msg string, p kyber.Point) { + ped := p.(*edwards25519.Point) + var str []string + str = append(str, fmt.Sprint("Representations of a point:")) + str = append(str, fmt.Sprintf("\tCompressed: %s", ped.String())) + str = append(str, fmt.Sprintf("\tLittle-endian X / Y:\n\t\tX: %x\n\t\tY: %x", ped.X_LE(), ped.Y_LE())) + str = append(str, fmt.Sprintf("\tDecimal X / Y:\n\t\tX: %s\n\t\tY: %s", + LEBytesToDecimal(ped.X_LE()).String(), + LEBytesToDecimal(ped.Y_LE()).String())) + log.Info(msg, strings.Join(str, "\n")) +} From 28e779aa3aa3f44f095faddfa9b8b3b7500e963c Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Fri, 10 May 2019 14:54:48 +0200 Subject: [PATCH 20/21] updated README --- ocs/demo/README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ocs/demo/README.md b/ocs/demo/README.md index 99c2f7a9c0..4e97857857 100644 --- a/ocs/demo/README.md +++ b/ocs/demo/README.md @@ -8,19 +8,20 @@ Demo This demo does a simple run to show how to use the OCS with the X509 certificates. To run it, you first need to run the docker image -to start 3 nodes locally: +to start 3 nodes locally. This command supposes you are in the +`ocs/demo` directory. ```bash +docker pull c4dt/ocs:dev docker run -it -p 7770-7775:7770-7775 --rm -v$(pwd)/data:/conode_data -e COTHORITY_ALLOW_INSECURE_ADMIN=true c4dt/ocs:dev ./run_nodes.sh -n 3 -v 2 -c -d /conode_data ``` This creates 3 nodes that are listening on the localhost using the ports 7770-7775. All data is stored in the `$(pwd)/data` directory. Once the nodes are up and running, -the demo can be started: +the demo can be started. This command supposes you are in the `ocs/demo` directory. ```bash -cd cothority/ocs/demo -go run main.go +go run main.go data/public.toml ``` The demo will do the following: From 52f914f357a34583c8efa9cceab5149ac9f1854d Mon Sep 17 00:00:00 2001 From: Linus Gasser Date: Fri, 10 May 2019 15:03:51 +0200 Subject: [PATCH 21/21] including kyber for running with print x/y coordinates --- conode/Makefile | 4 +- go.mod | 2 + kyber/.gitattributes | 2 + kyber/.gitignore | 18 + kyber/.travis.yml | 21 + kyber/LICENSE | 375 +++++++++ kyber/Makefile | 38 + kyber/README.md | 72 ++ kyber/doc.go | 123 +++ kyber/encoding.go | 49 ++ kyber/encrypt/ecies/ecies.go | 126 +++ kyber/encrypt/ecies/ecies_test.go | 46 + kyber/examples/dh_test.go | 49 ++ kyber/examples/enc_test.go | 87 ++ kyber/examples/main.go | 4 + kyber/examples/sig_test.go | 121 +++ kyber/go.mod | 9 + kyber/go.sum | 15 + kyber/group.go | 165 ++++ kyber/group/curve25519/basic.go | 213 +++++ kyber/group/curve25519/basic_test.go | 72 ++ kyber/group/curve25519/curve.go | 396 +++++++++ kyber/group/curve25519/curve_test.go | 143 ++++ kyber/group/curve25519/ext.go | 294 +++++++ kyber/group/curve25519/param.go | 159 ++++ kyber/group/curve25519/proj.go | 262 ++++++ kyber/group/curve25519/suite.go | 63 ++ {ocs => kyber/group}/edwards25519/LICENSE | 0 .../group}/edwards25519/allowvt_test.go | 0 {ocs => kyber/group}/edwards25519/const.go | 0 {ocs => kyber/group}/edwards25519/curve.go | 0 .../group}/edwards25519/curve_test.go | 0 {ocs => kyber/group}/edwards25519/fe.go | 0 {ocs => kyber/group}/edwards25519/ge.go | 0 .../group}/edwards25519/ge_mult_vartime.go | 0 {ocs => kyber/group}/edwards25519/marshal.go | 0 {ocs => kyber/group}/edwards25519/point.go | 0 .../group}/edwards25519/point_test.go | 0 .../group}/edwards25519/point_vartime.go | 0 {ocs => kyber/group}/edwards25519/scalar.go | 0 .../group}/edwards25519/scalar_test.go | 0 {ocs => kyber/group}/edwards25519/suite.go | 0 kyber/group/internal/marshalling/marshal.go | 83 ++ kyber/group/mod/int.go | 430 ++++++++++ kyber/group/mod/int_test.go | 90 ++ kyber/group/nist/curve.go | 266 ++++++ kyber/group/nist/doc.go | 3 + kyber/group/nist/group_test.go | 46 + kyber/group/nist/p256.go | 76 ++ kyber/group/nist/qrsuite.go | 67 ++ kyber/group/nist/residue.go | 314 +++++++ kyber/group/nist/suite.go | 62 ++ kyber/hash.go | 8 + kyber/pairing/adapter.go | 51 ++ kyber/pairing/adapter_test.go | 28 + kyber/pairing/bn256/LICENSE | 27 + kyber/pairing/bn256/README.md | 21 + kyber/pairing/bn256/constants.go | 56 ++ kyber/pairing/bn256/curve.go | 243 ++++++ kyber/pairing/bn256/gfp.go | 69 ++ kyber/pairing/bn256/gfp.h | 32 + kyber/pairing/bn256/gfp12.go | 231 +++++ kyber/pairing/bn256/gfp2.go | 159 ++++ kyber/pairing/bn256/gfp6.go | 224 +++++ kyber/pairing/bn256/gfp_amd64.s | 129 +++ kyber/pairing/bn256/gfp_arm64.s | 113 +++ kyber/pairing/bn256/gfp_decl.go | 24 + kyber/pairing/bn256/gfp_generic.go | 173 ++++ kyber/pairing/bn256/group.go | 78 ++ kyber/pairing/bn256/mul_amd64.h | 181 ++++ kyber/pairing/bn256/mul_arm64.h | 133 +++ kyber/pairing/bn256/mul_bmi2_amd64.h | 112 +++ kyber/pairing/bn256/optate.go | 268 ++++++ kyber/pairing/bn256/point.go | 647 ++++++++++++++ kyber/pairing/bn256/point_test.go | 41 + kyber/pairing/bn256/suite.go | 162 ++++ kyber/pairing/bn256/suite_test.go | 351 ++++++++ kyber/pairing/bn256/twist.go | 212 +++++ kyber/pairing/pairing.go | 17 + kyber/proof/clique.go | 45 + kyber/proof/context.go | 56 ++ kyber/proof/deniable.go | 297 +++++++ kyber/proof/deniable_test.go | 123 +++ kyber/proof/dleq/dleq.go | 134 +++ kyber/proof/dleq/dleq_test.go | 61 ++ kyber/proof/hash.go | 154 ++++ kyber/proof/hash_test.go | 167 ++++ kyber/proof/proof.go | 769 +++++++++++++++++ kyber/proof/proof_test.go | 248 ++++++ kyber/random.go | 13 + kyber/share/dkg/pedersen/dkg.go | 715 ++++++++++++++++ kyber/share/dkg/pedersen/dkg_test.go | 788 ++++++++++++++++++ kyber/share/dkg/pedersen/structs.go | 77 ++ kyber/share/dkg/rabin/dkg.go | 695 +++++++++++++++ kyber/share/dkg/rabin/dkg_test.go | 695 +++++++++++++++ kyber/share/poly.go | 523 ++++++++++++ kyber/share/poly_test.go | 458 ++++++++++ kyber/share/pvss/pvss.go | 190 +++++ kyber/share/pvss/pvss_test.go | 258 ++++++ kyber/share/vss/pedersen/dh.go | 52 ++ kyber/share/vss/pedersen/vss.go | 777 +++++++++++++++++ kyber/share/vss/pedersen/vss_test.go | 640 ++++++++++++++ kyber/share/vss/rabin/dh.go | 56 ++ kyber/share/vss/rabin/vss.go | 765 +++++++++++++++++ kyber/share/vss/rabin/vss_test.go | 609 ++++++++++++++ kyber/shuffle/biffle.go | 91 ++ kyber/shuffle/biffle_test.go | 63 ++ kyber/shuffle/pair.go | 379 +++++++++ kyber/shuffle/shuffle_test.go | 66 ++ kyber/shuffle/simple.go | 256 ++++++ kyber/shuffle/vartime_test.go | 19 + kyber/sign/anon/anon.go | 10 + kyber/sign/anon/enc.go | 187 +++++ kyber/sign/anon/enc_test.go | 96 +++ kyber/sign/anon/sig.go | 251 ++++++ kyber/sign/anon/sig_test.go | 313 +++++++ kyber/sign/anon/suite.go | 13 + kyber/sign/bls/bls.go | 138 +++ kyber/sign/bls/bls_test.go | 227 +++++ kyber/sign/cosi/cosi.go | 405 +++++++++ kyber/sign/cosi/cosi_test.go | 190 +++++ kyber/sign/cosi/suite.go | 10 + kyber/sign/dss/dss.go | 245 ++++++ kyber/sign/dss/dss_test.go | 225 +++++ kyber/sign/eddsa/eddsa.go | 171 ++++ kyber/sign/eddsa/eddsa_test.go | 181 ++++ kyber/sign/eddsa/testdata/sign.input.gz | Bin 0 -> 784638 bytes kyber/sign/schnorr/schnorr.go | 108 +++ kyber/sign/schnorr/schnorr_test.go | 98 +++ kyber/sign/tbls/tbls.go | 107 +++ kyber/sign/tbls/tbls_test.go | 31 + kyber/suites/all.go | 22 + kyber/suites/suites.go | 67 ++ kyber/suites/suites_test.go | 40 + kyber/util/encoding/encoding.go | 96 +++ kyber/util/encoding/encoding_test.go | 62 ++ kyber/util/key/key.go | 49 ++ kyber/util/key/key_test.go | 39 + kyber/util/random/rand.go | 78 ++ kyber/util/test/doc.go | 3 + kyber/util/test/group.go | 150 ++++ kyber/util/test/test.go | 433 ++++++++++ kyber/xof.go | 50 ++ kyber/xof/blake2xb/blake.go | 85 ++ kyber/xof/blake2xs/blake.go | 85 ++ kyber/xof/doc.go | 3 + kyber/xof/keccak/keccak.go | 68 ++ kyber/xof/xof_test.go | 239 ++++++ ocs/demo/.gitignore | 3 + ocs/demo/data/co1/private.toml | 24 + ocs/demo/data/co1/public.toml | 15 + ocs/demo/data/co2/private.toml | 24 + ocs/demo/data/co2/public.toml | 15 + ocs/demo/data/co3/private.toml | 24 + ocs/demo/data/co3/public.toml | 15 + ocs/demo/data/public.toml | 45 + ocs/demo/main.go | 4 +- 157 files changed, 23133 insertions(+), 5 deletions(-) create mode 100644 kyber/.gitattributes create mode 100644 kyber/.gitignore create mode 100644 kyber/.travis.yml create mode 100644 kyber/LICENSE create mode 100644 kyber/Makefile create mode 100644 kyber/README.md create mode 100644 kyber/doc.go create mode 100644 kyber/encoding.go create mode 100644 kyber/encrypt/ecies/ecies.go create mode 100644 kyber/encrypt/ecies/ecies_test.go create mode 100644 kyber/examples/dh_test.go create mode 100644 kyber/examples/enc_test.go create mode 100644 kyber/examples/main.go create mode 100644 kyber/examples/sig_test.go create mode 100644 kyber/go.mod create mode 100644 kyber/go.sum create mode 100644 kyber/group.go create mode 100644 kyber/group/curve25519/basic.go create mode 100644 kyber/group/curve25519/basic_test.go create mode 100644 kyber/group/curve25519/curve.go create mode 100644 kyber/group/curve25519/curve_test.go create mode 100644 kyber/group/curve25519/ext.go create mode 100644 kyber/group/curve25519/param.go create mode 100644 kyber/group/curve25519/proj.go create mode 100644 kyber/group/curve25519/suite.go rename {ocs => kyber/group}/edwards25519/LICENSE (100%) rename {ocs => kyber/group}/edwards25519/allowvt_test.go (100%) rename {ocs => kyber/group}/edwards25519/const.go (100%) rename {ocs => kyber/group}/edwards25519/curve.go (100%) rename {ocs => kyber/group}/edwards25519/curve_test.go (100%) rename {ocs => kyber/group}/edwards25519/fe.go (100%) rename {ocs => kyber/group}/edwards25519/ge.go (100%) rename {ocs => kyber/group}/edwards25519/ge_mult_vartime.go (100%) rename {ocs => kyber/group}/edwards25519/marshal.go (100%) rename {ocs => kyber/group}/edwards25519/point.go (100%) rename {ocs => kyber/group}/edwards25519/point_test.go (100%) rename {ocs => kyber/group}/edwards25519/point_vartime.go (100%) rename {ocs => kyber/group}/edwards25519/scalar.go (100%) rename {ocs => kyber/group}/edwards25519/scalar_test.go (100%) rename {ocs => kyber/group}/edwards25519/suite.go (100%) create mode 100644 kyber/group/internal/marshalling/marshal.go create mode 100644 kyber/group/mod/int.go create mode 100644 kyber/group/mod/int_test.go create mode 100644 kyber/group/nist/curve.go create mode 100644 kyber/group/nist/doc.go create mode 100644 kyber/group/nist/group_test.go create mode 100644 kyber/group/nist/p256.go create mode 100644 kyber/group/nist/qrsuite.go create mode 100644 kyber/group/nist/residue.go create mode 100644 kyber/group/nist/suite.go create mode 100644 kyber/hash.go create mode 100644 kyber/pairing/adapter.go create mode 100644 kyber/pairing/adapter_test.go create mode 100644 kyber/pairing/bn256/LICENSE create mode 100644 kyber/pairing/bn256/README.md create mode 100644 kyber/pairing/bn256/constants.go create mode 100644 kyber/pairing/bn256/curve.go create mode 100644 kyber/pairing/bn256/gfp.go create mode 100644 kyber/pairing/bn256/gfp.h create mode 100644 kyber/pairing/bn256/gfp12.go create mode 100644 kyber/pairing/bn256/gfp2.go create mode 100644 kyber/pairing/bn256/gfp6.go create mode 100644 kyber/pairing/bn256/gfp_amd64.s create mode 100644 kyber/pairing/bn256/gfp_arm64.s create mode 100644 kyber/pairing/bn256/gfp_decl.go create mode 100644 kyber/pairing/bn256/gfp_generic.go create mode 100644 kyber/pairing/bn256/group.go create mode 100644 kyber/pairing/bn256/mul_amd64.h create mode 100644 kyber/pairing/bn256/mul_arm64.h create mode 100644 kyber/pairing/bn256/mul_bmi2_amd64.h create mode 100644 kyber/pairing/bn256/optate.go create mode 100644 kyber/pairing/bn256/point.go create mode 100644 kyber/pairing/bn256/point_test.go create mode 100644 kyber/pairing/bn256/suite.go create mode 100644 kyber/pairing/bn256/suite_test.go create mode 100644 kyber/pairing/bn256/twist.go create mode 100644 kyber/pairing/pairing.go create mode 100644 kyber/proof/clique.go create mode 100644 kyber/proof/context.go create mode 100644 kyber/proof/deniable.go create mode 100644 kyber/proof/deniable_test.go create mode 100644 kyber/proof/dleq/dleq.go create mode 100644 kyber/proof/dleq/dleq_test.go create mode 100644 kyber/proof/hash.go create mode 100644 kyber/proof/hash_test.go create mode 100644 kyber/proof/proof.go create mode 100644 kyber/proof/proof_test.go create mode 100644 kyber/random.go create mode 100644 kyber/share/dkg/pedersen/dkg.go create mode 100644 kyber/share/dkg/pedersen/dkg_test.go create mode 100644 kyber/share/dkg/pedersen/structs.go create mode 100644 kyber/share/dkg/rabin/dkg.go create mode 100644 kyber/share/dkg/rabin/dkg_test.go create mode 100644 kyber/share/poly.go create mode 100644 kyber/share/poly_test.go create mode 100644 kyber/share/pvss/pvss.go create mode 100644 kyber/share/pvss/pvss_test.go create mode 100644 kyber/share/vss/pedersen/dh.go create mode 100644 kyber/share/vss/pedersen/vss.go create mode 100644 kyber/share/vss/pedersen/vss_test.go create mode 100644 kyber/share/vss/rabin/dh.go create mode 100644 kyber/share/vss/rabin/vss.go create mode 100644 kyber/share/vss/rabin/vss_test.go create mode 100644 kyber/shuffle/biffle.go create mode 100644 kyber/shuffle/biffle_test.go create mode 100644 kyber/shuffle/pair.go create mode 100644 kyber/shuffle/shuffle_test.go create mode 100644 kyber/shuffle/simple.go create mode 100644 kyber/shuffle/vartime_test.go create mode 100644 kyber/sign/anon/anon.go create mode 100644 kyber/sign/anon/enc.go create mode 100644 kyber/sign/anon/enc_test.go create mode 100644 kyber/sign/anon/sig.go create mode 100644 kyber/sign/anon/sig_test.go create mode 100644 kyber/sign/anon/suite.go create mode 100644 kyber/sign/bls/bls.go create mode 100644 kyber/sign/bls/bls_test.go create mode 100644 kyber/sign/cosi/cosi.go create mode 100644 kyber/sign/cosi/cosi_test.go create mode 100644 kyber/sign/cosi/suite.go create mode 100644 kyber/sign/dss/dss.go create mode 100644 kyber/sign/dss/dss_test.go create mode 100644 kyber/sign/eddsa/eddsa.go create mode 100644 kyber/sign/eddsa/eddsa_test.go create mode 100644 kyber/sign/eddsa/testdata/sign.input.gz create mode 100644 kyber/sign/schnorr/schnorr.go create mode 100644 kyber/sign/schnorr/schnorr_test.go create mode 100644 kyber/sign/tbls/tbls.go create mode 100644 kyber/sign/tbls/tbls_test.go create mode 100644 kyber/suites/all.go create mode 100644 kyber/suites/suites.go create mode 100644 kyber/suites/suites_test.go create mode 100644 kyber/util/encoding/encoding.go create mode 100644 kyber/util/encoding/encoding_test.go create mode 100644 kyber/util/key/key.go create mode 100644 kyber/util/key/key_test.go create mode 100644 kyber/util/random/rand.go create mode 100644 kyber/util/test/doc.go create mode 100644 kyber/util/test/group.go create mode 100644 kyber/util/test/test.go create mode 100644 kyber/xof.go create mode 100644 kyber/xof/blake2xb/blake.go create mode 100644 kyber/xof/blake2xs/blake.go create mode 100644 kyber/xof/doc.go create mode 100644 kyber/xof/keccak/keccak.go create mode 100644 kyber/xof/xof_test.go create mode 100644 ocs/demo/.gitignore create mode 100644 ocs/demo/data/co1/private.toml create mode 100644 ocs/demo/data/co1/public.toml create mode 100644 ocs/demo/data/co2/private.toml create mode 100644 ocs/demo/data/co2/public.toml create mode 100644 ocs/demo/data/co3/private.toml create mode 100644 ocs/demo/data/co3/public.toml create mode 100644 ocs/demo/data/public.toml diff --git a/conode/Makefile b/conode/Makefile index 7b23b5029f..cc503ed3cf 100644 --- a/conode/Makefile +++ b/conode/Makefile @@ -56,8 +56,8 @@ clean: verify: GO111MODULE=on go mod verify - @echo "Checking for replace in go.mod..." - @if GO111MODULE=on go list -m all | grep --quiet '=>'; then exit 1; fi + #@echo "Checking for replace in go.mod..." + #@if GO111MODULE=on go list -m all | grep --quiet '=>'; then exit 1; fi # The suffix on conode exe is the result from: echo `uname -s`.`uname -m` # so that we can find the right one in the wrapper script. diff --git a/go.mod b/go.mod index 2beeb1ce6f..afb1ee0021 100644 --- a/go.mod +++ b/go.mod @@ -23,3 +23,5 @@ require ( gopkg.in/square/go-jose.v2 v2.2.2 // indirect gopkg.in/urfave/cli.v1 v1.20.0 ) + +replace go.dedis.ch/kyber/v3 => ./kyber diff --git a/kyber/.gitattributes b/kyber/.gitattributes new file mode 100644 index 0000000000..a5e27ec9a0 --- /dev/null +++ b/kyber/.gitattributes @@ -0,0 +1,2 @@ +go.mod linguist-generated=false +go.sum linguist-generated=false diff --git a/kyber/.gitignore b/kyber/.gitignore new file mode 100644 index 0000000000..f615171a7b --- /dev/null +++ b/kyber/.gitignore @@ -0,0 +1,18 @@ +*.iml +*.o +*.pyc +*.swp +*~ +moc_* +ext/ +dissent +docs/html +test.log +libdissent.so* +keygen +*.moc +entry_tunnel +exit_tunnel +.DS_Store +*.cov +profile.tmp \ No newline at end of file diff --git a/kyber/.travis.yml b/kyber/.travis.yml new file mode 100644 index 0000000000..7a6cc36875 --- /dev/null +++ b/kyber/.travis.yml @@ -0,0 +1,21 @@ +language: go + +go: + - "1.11.x" + +go_import_path: go.dedis.ch/kyber/v3 + +install: + - go get github.com/dedis/Coding || true + +script: + - env GO111MODULE=on make test + +notifications: + email: false + +# https://restic.net/blog/2018-09-02/travis-build-cache +cache: + directories: + - $HOME/.cache/go-build + - $GOPATH/pkg/mod diff --git a/kyber/LICENSE b/kyber/LICENSE new file mode 100644 index 0000000000..411d65a24c --- /dev/null +++ b/kyber/LICENSE @@ -0,0 +1,375 @@ +This code is (c) by DEDIS/EPFL 2017 under the MPL v2 or later version. + +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. \ No newline at end of file diff --git a/kyber/Makefile b/kyber/Makefile new file mode 100644 index 0000000000..01cfb50918 --- /dev/null +++ b/kyber/Makefile @@ -0,0 +1,38 @@ +all: test + +gopath=$(shell go env GOPATH) +CODING = $(gopath)/src/github.com/dedis/Coding/bin + +test_fmt: + @echo Checking correct formatting of files + @{ \ + files=$$( go fmt ./... ); \ + if [ -n "$$files" ]; then \ + echo "Files not properly formatted: $$files"; \ + exit 1; \ + fi; \ + if ! go vet ./...; then \ + exit 1; \ + fi \ + } + +test_lint: + @echo Checking linting of files + @{ \ + go get -u github.com/golang/lint/golint; \ + lintfiles=$$( golint ./... | egrep -v _test.go ); \ + if [ -n "$$lintfiles" ]; then \ + echo "Lint errors:"; \ + echo "$$lintfiles"; \ + exit 1; \ + fi \ + } + +test_goveralls: + go get github.com/mattn/goveralls + $(CODING)/coveralls.sh $(EXCLUDE_TEST) + $(gopath)/bin/goveralls -coverprofile=profile.cov -service=travis-ci || true + +test: test_fmt test_lint test_goveralls + + diff --git a/kyber/README.md b/kyber/README.md new file mode 100644 index 0000000000..30de55e640 --- /dev/null +++ b/kyber/README.md @@ -0,0 +1,72 @@ +[![Docs](https://img.shields.io/badge/docs-current-brightgreen.svg)](https://godoc.org/go.dedis.ch/kyber) +[![Build Status](https://travis-ci.org/dedis/kyber.svg?branch=master)](https://travis-ci.org/dedis/kyber) + +DEDIS Advanced Crypto Library for Go +==================================== + +This package provides a toolbox of advanced cryptographic primitives for Go, +targeting applications like [Cothority](https://go.dedis.ch/cothority) +that need more than straightforward signing and encryption. +Please see the +[Godoc documentation for this package](https://godoc.org/go.dedis.ch/kyber) +for details on the library's purpose and API functionality. + +This package includes a mix of variable time and constant time +implementations. If your application is sensitive to timing-based attacks +and you need to constrain Kyber to offering only constant time implementations, +you should use the [suites.RequireConstantTime()](https://godoc.org/go.dedis.ch/kyber/suites#RequireConstantTime) +function in the `init()` function of your `main` package. + +Versioning - Development +------------------------ + +We use the following versioning model: + +* crypto.v0 was the first semi-stable version. See [migration notes](https://github.com/dedis/kyber/wiki/Migration-from-gopkg.in-dedis-crypto.v0). +* kyber.v1 never existed, in order to keep kyber, onet and cothorithy versions linked +* gopkg.in/dedis/kyber.v2 was the last stable version +* Starting with v3.0.0, kyber is a Go module, and we respect [semantic versioning](https://golang.org/cmd/go/#hdr-Module_compatibility_and_semantic_versioning). + +So if you depend on the master branch, you can expect breakages from time +to time. If you need something that doesn't change in a backward-compatible +way you should use have a `go.mod` file in the directory where your +main package is. + +Installing +---------- + +First make sure you have [Go](https://golang.org) version 1.11 or newer installed. + +The basic crypto library requires only Go and a few +third-party Go-language dependencies that can be installed automatically +as follows: + + go get go.dedis.ch/kyber + +You can recursively test all the packages in the library as follows: + + go test -v ./... + +A note on deriving shared secrets +--------------------------------- + +Traditionally, ECDH (Elliptic curve Diffie-Hellman) derives the shared secret +from the x point only. In this framework, you can either manually retrieve the +value or use the MarshalBinary method to take the combined (x, y) value as the +shared secret. We recommend the latter process for new softare/protocols using +this framework as it is cleaner and generalizes across different types of groups +(e.g., both integer and elliptic curves), although it will likely be +incompatible with other implementations of ECDH. See [the Wikipedia +page](http://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman) on +ECDH. + +Reporting security problems +--------------------------- + +This library is offered as-is, and without a guarantee. It will need an +independent security review before it should be considered ready for use in +security-critical applications. If you integrate Kyber into your application it +is YOUR RESPONSIBILITY to arrange for that audit. + +If you notice a possible security problem, please report it +to dedis-security@epfl.ch. diff --git a/kyber/doc.go b/kyber/doc.go new file mode 100644 index 0000000000..b20959ef64 --- /dev/null +++ b/kyber/doc.go @@ -0,0 +1,123 @@ +/* +Package kyber provides a toolbox of advanced cryptographic primitives, +for applications that need more than straightforward signing and encryption. +This top level package defines the interfaces to cryptographic primitives +designed to be independent of specific cryptographic algorithms, +to facilitate upgrading applications to new cryptographic algorithms +or switching to alternative algorithms for experimentation purposes. + +Abstract Groups + +This toolkits public-key crypto API includes a kyber.Group interface +supporting a broad class of group-based public-key primitives +including DSA-style integer residue groups and elliptic curve groups. Users of +this API can write higher-level crypto algorithms such as zero-knowledge +proofs without knowing or caring exactly what kind of group, let alone which +precise security parameters or elliptic curves, are being used. The kyber.Group +interface supports the standard algebraic operations on group elements and +scalars that nontrivial public-key algorithms tend to rely on. The interface +uses additive group terminology typical for elliptic curves, such that point +addition is homomorphically equivalent to adding their (potentially secret) +scalar multipliers. But the API and its operations apply equally well to +DSA-style integer groups. + +As a trivial example, generating a public/private keypair is as simple as: + + suite := suites.MustFind("Ed25519") // Use the edwards25519-curve + a := suite.Scalar().Pick(suite.RandomStream()) // Alice's private key + A := suite.Point().Mul(a, nil) // Alice's public key + +The first statement picks a private key (Scalar) from a the suites's source of +cryptographic random or pseudo-random bits, while the second performs elliptic +curve scalar multiplication of the curve's standard base point (indicated by the +'nil' argument to Mul) by the scalar private key 'a'. Similarly, computing a +Diffie-Hellman shared secret using Alice's private key 'a' and Bob's public key +'B' can be done via: + + S := suite.Point().Mul(a, B) // Shared Diffie-Hellman secret + +Note that we use 'Mul' rather than 'Exp' here because the library uses +the additive-group terminology common for elliptic curve crypto, +rather than the multiplicative-group terminology of traditional +integer groups - but the two are semantically equivalent and the +interface itself works for both elliptic curve and integer groups. + +Higher-level Building Blocks + +Various sub-packages provide several specific +implementations of these cryptographic interfaces. +In particular, the 'group/mod' sub-package provides implementations +of modular integer groups underlying conventional DSA-style algorithms. +The `group/nist` package provides NIST-standardized elliptic curves built on +the Go crypto library. +The 'group/edwards25519' sub-package provides the kyber.Group interface +using the popular Ed25519 curve. + +Other sub-packages build more interesting high-level cryptographic tools +atop these primitive interfaces, including: + +- share: Polynomial commitment and verifiable Shamir secret splitting +for implementing verifiable 't-of-n' threshold cryptographic schemes. +This can be used to encrypt a message so that any 2 out of 3 receivers +must work together to decrypt it, for example. + +- proof: An implementation of the general Camenisch/Stadler framework +for discrete logarithm knowledge proofs. +This system supports both interactive and non-interactive proofs +of a wide variety of statements such as, +"I know the secret x associated with public key X +or I know the secret y associated with public key Y", +without revealing anything about either secret +or even which branch of the "or" clause is true. + +- sign: The sign directory contains different signature schemes. + +- sign/anon provides anonymous and pseudonymous public-key encryption and signing, +where the sender of a signed message or the receiver of an encrypted message +is defined as an explicit anonymity set containing several public keys +rather than just one. For example, a member of an organization's board of trustees +might prove to be a member of the board without revealing which member she is. + +- sign/cosi provides collective signature algorithm, where a bunch of signers create a +unique, compact and efficiently verifiable signature using the Schnorr signature as a basis. + +- sign/eddsa provides a kyber-native implementation of the EdDSA signature scheme. + +- sign/schnorr provides a basic vanilla Schnorr signature scheme implementation. + +- shuffle: Verifiable cryptographic shuffles of ElGamal ciphertexts, +which can be used to implement (for example) voting or auction schemes +that keep the sources of individual votes or bids private +without anyone having to trust more than one of the shuffler(s) to shuffle +votes/bids honestly. + +Target Use-cases + +As should be obvious, this library is intended to be used by +developers who are at least moderately knowledgeable about +cryptography. If you want a crypto library that makes it easy to +implement "basic crypto" functionality correctly - i.e., plain +public-key encryption and signing - then +[NaCl secretbox](https://godoc.org/golang.org/x/crypto/nacl/secretbox) +may be a better choice. This toolkit's purpose is to make it possible +- and preferably easy - to do slightly more interesting things that +most current crypto libraries don't support effectively. The one +existing crypto library that this toolkit is probably most comparable +to is the Charm rapid prototyping library for Python +(https://charm-crypto.com/category/charm). + +This library incorporates and/or builds on existing code from a variety of +sources, as documented in the relevant sub-packages. + +Reporting Security Problems + +This library is offered as-is, and without a guarantee. It will need an +independent security review before it should be considered ready for use in +security-critical applications. If you integrate Kyber into your application it +is YOUR RESPONSIBILITY to arrange for that audit. + +If you notice a possible security problem, please report it +to dedis-security@epfl.ch. + +*/ +package kyber diff --git a/kyber/encoding.go b/kyber/encoding.go new file mode 100644 index 0000000000..3b927733d0 --- /dev/null +++ b/kyber/encoding.go @@ -0,0 +1,49 @@ +package kyber + +import ( + "encoding" + "io" +) + +/* +Marshaling is a basic interface representing fixed-length (or known-length) +cryptographic objects or structures having a built-in binary encoding. +Implementors must ensure that calls to these methods do not modify +the underlying object so that other users of the object can access +it concurrently. +*/ +type Marshaling interface { + encoding.BinaryMarshaler + encoding.BinaryUnmarshaler + + // String returns the human readable string representation of the object. + String() string + + // Encoded length of this object in bytes. + MarshalSize() int + + // Encode the contents of this object and write it to an io.Writer. + MarshalTo(w io.Writer) (int, error) + + // Decode the content of this object by reading from an io.Reader. + // If r is an XOF, it uses r to pick a valid object pseudo-randomly, + // which may entail reading more than Len bytes due to retries. + UnmarshalFrom(r io.Reader) (int, error) +} + +// Encoding represents an abstract interface to an encoding/decoding that can be +// used to marshal/unmarshal objects to and from streams. Different Encodings +// will have different constraints, of course. Two implementations are +// available: +// +// 1. The protobuf encoding using the variable length Google Protobuf encoding +// scheme. The library is available at https://go.dedis.ch/protobuf +// 2. The fixbuf encoding, a fixed length binary encoding of arbitrary +// structures. The library is available at https://go.dedis.ch/fixbuf. +type Encoding interface { + // Encode and write objects to an io.Writer. + Write(w io.Writer, objs ...interface{}) error + + // Read and decode objects from an io.Reader. + Read(r io.Reader, objs ...interface{}) error +} diff --git a/kyber/encrypt/ecies/ecies.go b/kyber/encrypt/ecies/ecies.go new file mode 100644 index 0000000000..eabc28f7a1 --- /dev/null +++ b/kyber/encrypt/ecies/ecies.go @@ -0,0 +1,126 @@ +// Package ecies implements the Elliptic Curve Integrated Encryption Scheme (ECIES). +package ecies + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/sha256" + "errors" + "hash" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/util/random" + "golang.org/x/crypto/hkdf" +) + +// Encrypt first computes a shared DH key using the given public key, then +// HKDF-derives a symmetric key (and nonce) from that, and finally uses these +// values to encrypt the given message via AES-GCM. If the hash input parameter +// is nil then SHA256 is used as a default. Encrypt returns a byte slice +// containing the ephemeral elliptic curve point of the DH key exchange and the +// ciphertext or an error. +func Encrypt(group kyber.Group, public kyber.Point, message []byte, hash func() hash.Hash) ([]byte, error) { + if hash == nil { + hash = sha256.New + } + + // Generate an ephemeral elliptic curve scalar and point + r := group.Scalar().Pick(random.New()) + R := group.Point().Mul(r, nil) + + // Compute shared DH key + dh := group.Point().Mul(r, public) + + // Derive symmetric key and nonce via HKDF (NOTE: Since we use a new + // ephemeral key for every ECIES encryption and thus have a fresh + // HKDF-derived key for AES-GCM, the nonce for AES-GCM can be an arbitrary + // (even static) value. We derive it here simply via HKDF as well.) + len := 32 + 12 + buf, err := deriveKey(hash, dh, len) + if err != nil { + return nil, err + } + key := buf[:32] + nonce := buf[32:len] + + // Encrypt message using AES-GCM + aes, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + aesgcm, err := cipher.NewGCM(aes) + if err != nil { + return nil, err + } + c := aesgcm.Seal(nil, nonce, message, nil) + + // Serialize ephemeral elliptic curve point and ciphertext + var ctx bytes.Buffer + _, err = R.MarshalTo(&ctx) + if err != nil { + return nil, err + } + _, err = ctx.Write(c) + if err != nil { + return nil, err + } + return ctx.Bytes(), nil +} + +// Decrypt first computes a shared DH key using the received ephemeral elliptic +// curve point (stored in the first part of ctx), then HKDF-derives a symmetric +// key (and nonce) from that, and finally uses these values to decrypt the +// given ciphertext (stored in the second part of ctx) via AES-GCM. If the hash +// input parameter is nil then SHA256 is used as a default. Decrypt returns the +// plaintext message or an error. +func Decrypt(group kyber.Group, private kyber.Scalar, ctx []byte, hash func() hash.Hash) ([]byte, error) { + if hash == nil { + hash = sha256.New + } + + // Reconstruct the ephemeral elliptic curve point + R := group.Point() + l := group.PointLen() + if err := R.UnmarshalBinary(ctx[:l]); err != nil { + return nil, err + } + + // Compute shared DH key and derive the symmetric key and nonce via HKDF + dh := group.Point().Mul(private, R) + len := 32 + 12 + buf, err := deriveKey(hash, dh, len) + if err != nil { + return nil, err + } + key := buf[:32] + nonce := buf[32:len] + + // Decrypt message using AES-GCM + aes, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + aesgcm, err := cipher.NewGCM(aes) + if err != nil { + return nil, err + } + return aesgcm.Open(nil, nonce, ctx[l:], nil) +} + +func deriveKey(hash func() hash.Hash, dh kyber.Point, len int) ([]byte, error) { + dhb, err := dh.MarshalBinary() + if err != nil { + return nil, err + } + hkdf := hkdf.New(hash, dhb, nil, nil) + key := make([]byte, len, len) + n, err := hkdf.Read(key) + if err != nil { + return nil, err + } + if n < len { + return nil, errors.New("ecies: hkdf-derived key too short") + } + return key, nil +} diff --git a/kyber/encrypt/ecies/ecies_test.go b/kyber/encrypt/ecies/ecies_test.go new file mode 100644 index 0000000000..9668a6e34f --- /dev/null +++ b/kyber/encrypt/ecies/ecies_test.go @@ -0,0 +1,46 @@ +package ecies + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/util/random" +) + +func TestECIES(t *testing.T) { + message := []byte("Hello ECIES") + suite := edwards25519.NewBlakeSHA256Ed25519() + private := suite.Scalar().Pick(random.New()) + public := suite.Point().Mul(private, nil) + ciphertext, err := Encrypt(suite, public, message, suite.Hash) + require.Nil(t, err) + plaintext, err := Decrypt(suite, private, ciphertext, suite.Hash) + require.Nil(t, err) + require.Equal(t, message, plaintext) +} + +func TestECIESFailPoint(t *testing.T) { + message := []byte("Hello ECIES") + suite := edwards25519.NewBlakeSHA256Ed25519() + private := suite.Scalar().Pick(random.New()) + public := suite.Point().Mul(private, nil) + ciphertext, err := Encrypt(suite, public, message, nil) + require.Nil(t, err) + ciphertext[0] ^= 0xff + _, err = Decrypt(suite, private, ciphertext, nil) + require.NotNil(t, err) +} + +func TestECIESFailCiphertext(t *testing.T) { + message := []byte("Hello ECIES") + suite := edwards25519.NewBlakeSHA256Ed25519() + private := suite.Scalar().Pick(random.New()) + public := suite.Point().Mul(private, nil) + ciphertext, err := Encrypt(suite, public, message, nil) + require.Nil(t, err) + l := suite.PointLen() + ciphertext[l] ^= 0xff + _, err = Decrypt(suite, private, ciphertext, nil) + require.NotNil(t, err) +} diff --git a/kyber/examples/dh_test.go b/kyber/examples/dh_test.go new file mode 100644 index 0000000000..7e47b53cd1 --- /dev/null +++ b/kyber/examples/dh_test.go @@ -0,0 +1,49 @@ +package examples + +import ( + "fmt" + + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +/* +This example illustrates how to use the crypto toolkit's kyber.group API +to perform basic Diffie-Hellman key exchange calculations, +using the NIST-standard P256 elliptic curve in this case. +Any other suitable elliptic curve or other cryptographic group may be used +simply by changing the first line that picks the suite. +*/ +func Example_diffieHellman() { + // A pseudo RNG which makes this code repeatable for testing. + rng := blake2xb.New(nil) + + // Crypto setup: NIST-standardized P256 curve with AES-128 and SHA-256 + // For production code, simply use edwards25519.NewBlakeSHA256Ed25519(). + suite := edwards25519.NewBlakeSHA256Ed25519WithRand(rng) + + // Alice's public/private keypair + a := suite.Scalar().Pick(rng) // Alice's private key + A := suite.Point().Mul(a, nil) // Alice's public key + + // Bob's public/private keypair + b := suite.Scalar().Pick(rng) // Alice's private key + B := suite.Point().Mul(b, nil) // Alice's public key + + // Assume Alice and Bob have securely obtained each other's public keys. + + // Alice computes their shared secret using Bob's public key. + SA := suite.Point().Mul(a, B) + + // Bob computes their shared secret using Alice's public key. + SB := suite.Point().Mul(b, A) + + // They had better be the same! + if !SA.Equal(SB) { + panic("Diffie-Hellman key exchange didn't work") + } + fmt.Println("Shared secret: " + SA.String()) + + // Output: + // Shared secret: 80ea238cacfdab279626970bba18c69083c7751865dec4c6434bff4351282847 +} diff --git a/kyber/examples/enc_test.go b/kyber/examples/enc_test.go new file mode 100644 index 0000000000..701820a1ac --- /dev/null +++ b/kyber/examples/enc_test.go @@ -0,0 +1,87 @@ +package examples + +import ( + "fmt" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/util/random" +) + +func ElGamalEncrypt(group kyber.Group, pubkey kyber.Point, message []byte) ( + K, C kyber.Point, remainder []byte) { + + // Embed the message (or as much of it as will fit) into a curve point. + M := group.Point().Embed(message, random.New()) + max := group.Point().EmbedLen() + if max > len(message) { + max = len(message) + } + remainder = message[max:] + // ElGamal-encrypt the point to produce ciphertext (K,C). + k := group.Scalar().Pick(random.New()) // ephemeral private key + K = group.Point().Mul(k, nil) // ephemeral DH public key + S := group.Point().Mul(k, pubkey) // ephemeral DH shared secret + C = S.Add(S, M) // message blinded with secret + return +} + +func ElGamalDecrypt(group kyber.Group, prikey kyber.Scalar, K, C kyber.Point) ( + message []byte, err error) { + + // ElGamal-decrypt the ciphertext (K,C) to reproduce the message. + S := group.Point().Mul(prikey, K) // regenerate shared secret + M := group.Point().Sub(C, S) // use to un-blind the message + message, err = M.Data() // extract the embedded data + return +} + +/* +This example illustrates how the crypto toolkit may be used +to perform "pure" ElGamal encryption, +in which the message to be encrypted is small enough to be embedded +directly within a group element (e.g., in an elliptic curve point). +For basic background on ElGamal encryption see for example +http://en.wikipedia.org/wiki/ElGamal_encryption. + +Most public-key crypto libraries tend not to support embedding data in points, +in part because for "vanilla" public-key encryption you don't need it: +one would normally just generate an ephemeral Diffie-Hellman secret +and use that to seed a symmetric-key crypto algorithm such as AES, +which is much more efficient per bit and works for arbitrary-length messages. +However, in many advanced public-key crypto algorithms it is often useful +to be able to embedded data directly into points and compute with them: +as just one of many examples, +the proactively verifiable anonymous messaging scheme prototyped in Verdict +(see http://dedis.cs.yale.edu/dissent/papers/verdict-abs). + +For fancier versions of ElGamal encryption implemented in this toolkit +see for example anon.Encrypt, which encrypts a message for +one of several possible receivers forming an explicit anonymity set. +*/ +func Example_elGamalEncryption() { + suite := edwards25519.NewBlakeSHA256Ed25519() + + // Create a public/private keypair + a := suite.Scalar().Pick(suite.RandomStream()) // Alice's private key + A := suite.Point().Mul(a, nil) // Alice's public key + + // ElGamal-encrypt a message using the public key. + m := []byte("The quick brown fox") + K, C, _ := ElGamalEncrypt(suite, A, m) + + // Decrypt it using the corresponding private key. + mm, err := ElGamalDecrypt(suite, a, K, C) + + // Make sure it worked! + if err != nil { + fmt.Println("decryption failed: " + err.Error()) + } + if string(mm) != string(m) { + fmt.Println("decryption produced wrong output: " + string(mm)) + } + fmt.Println("Decryption succeeded: " + string(mm)) + + // Output: + // Decryption succeeded: The quick brown fox +} diff --git a/kyber/examples/main.go b/kyber/examples/main.go new file mode 100644 index 0000000000..e55adcc024 --- /dev/null +++ b/kyber/examples/main.go @@ -0,0 +1,4 @@ +// Package examples provides a suite of tests showing how to use the different +// abstraction and protocols provided by the kyber library. To run the +// tests, simply do `go test -v` in this directory. +package examples diff --git a/kyber/examples/sig_test.go b/kyber/examples/sig_test.go new file mode 100644 index 0000000000..34878c9624 --- /dev/null +++ b/kyber/examples/sig_test.go @@ -0,0 +1,121 @@ +package examples + +import ( + "bytes" + "crypto/cipher" + "encoding/hex" + "errors" + "fmt" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" +) + +type Suite interface { + kyber.Group + kyber.Encoding + kyber.XOFFactory +} + +// A basic, verifiable signature +type basicSig struct { + C kyber.Scalar // challenge + R kyber.Scalar // response +} + +// Returns a secret that depends on on a message and a point +func hashSchnorr(suite Suite, message []byte, p kyber.Point) kyber.Scalar { + pb, _ := p.MarshalBinary() + c := suite.XOF(pb) + c.Write(message) + return suite.Scalar().Pick(c) +} + +// This simplified implementation of Schnorr Signatures is based on +// crypto/anon/sig.go +// The ring structure is removed and +// The anonimity set is reduced to one public key = no anonimity +func SchnorrSign(suite Suite, random cipher.Stream, message []byte, + privateKey kyber.Scalar) []byte { + + // Create random secret v and public point commitment T + v := suite.Scalar().Pick(random) + T := suite.Point().Mul(v, nil) + + // Create challenge c based on message and T + c := hashSchnorr(suite, message, T) + + // Compute response r = v - x*c + r := suite.Scalar() + r.Mul(privateKey, c).Sub(v, r) + + // Return verifiable signature {c, r} + // Verifier will be able to compute v = r + x*c + // And check that hashElgamal for T and the message == c + buf := bytes.Buffer{} + sig := basicSig{c, r} + _ = suite.Write(&buf, &sig) + return buf.Bytes() +} + +func SchnorrVerify(suite Suite, message []byte, publicKey kyber.Point, + signatureBuffer []byte) error { + + // Decode the signature + buf := bytes.NewBuffer(signatureBuffer) + sig := basicSig{} + if err := suite.Read(buf, &sig); err != nil { + return err + } + r := sig.R + c := sig.C + + // Compute base**(r + x*c) == T + var P, T kyber.Point + P = suite.Point() + T = suite.Point() + T.Add(T.Mul(r, nil), P.Mul(c, publicKey)) + + // Verify that the hash based on the message and T + // matches the challange c from the signature + c = hashSchnorr(suite, message, T) + if !c.Equal(sig.C) { + return errors.New("invalid signature") + } + + return nil +} + +// This example shows how to perform a simple Schnorr signature. Please, use this +// example as a reference to understand the abstraction only. There is a +// `sign/schnorr` package which provides Schnorr signatures functionality in a +// more secure manner. +func Example_schnorr() { + // Crypto setup + suite := edwards25519.NewBlakeSHA256Ed25519() + rand := suite.XOF([]byte("example")) + + // Create a public/private keypair (X,x) + x := suite.Scalar().Pick(rand) // create a private key x + X := suite.Point().Mul(x, nil) // corresponding public key X + + // Generate the signature + M := []byte("Hello World!") // message we want to sign + sig := SchnorrSign(suite, rand, M, x) + fmt.Print("Signature:\n" + hex.Dump(sig)) + + // Verify the signature against the correct message + err := SchnorrVerify(suite, M, X, sig) + if err != nil { + panic(err.Error()) + } + fmt.Println("Signature verified against correct message.") + + // Output: + // Signature: + // 00000000 67 3f 25 fe d1 51 5d 1e 64 3a f7 79 2f 55 53 7c |g?%..Q].d:.y/US|| + // 00000010 f6 8a 5a 73 d5 c7 db f4 07 58 37 cc 1c b8 bf 02 |..Zs.....X7.....| + // 00000020 5f 0b a0 ef 0e 3e 9d 2e 08 10 69 b9 82 5f 65 b3 |_....>....i.._e.| + // 00000030 51 f8 b8 59 9b 72 d1 d0 12 f0 c6 ac 00 2a 09 0f |Q..Y.r.......*..| + // Signature verified against correct message. +} diff --git a/kyber/go.mod b/kyber/go.mod new file mode 100644 index 0000000000..4e80f19763 --- /dev/null +++ b/kyber/go.mod @@ -0,0 +1,9 @@ +module go.dedis.ch/kyber/v3 + +require ( + github.com/stretchr/testify v1.3.0 + go.dedis.ch/fixbuf v1.0.3 + go.dedis.ch/protobuf v1.0.5 + golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b + golang.org/x/sys v0.0.0-20190124100055-b90733256f2e +) diff --git a/kyber/go.sum b/kyber/go.sum new file mode 100644 index 0000000000..08a7035346 --- /dev/null +++ b/kyber/go.sum @@ -0,0 +1,15 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= +go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= +go.dedis.ch/protobuf v1.0.5 h1:EbF1czEKICxf5KY8Tm7wMF28hcOQbB6yk4IybIFWTYE= +go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo= +golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b h1:Elez2XeF2p9uyVj0yEUDqQ56NFcDtcBNkYP7yv8YbUE= +golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190124100055-b90733256f2e h1:3GIlrlVLfkoipSReOMNAgApI0ajnalyLa/EZHHca/XI= +golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/kyber/group.go b/kyber/group.go new file mode 100644 index 0000000000..09612c7518 --- /dev/null +++ b/kyber/group.go @@ -0,0 +1,165 @@ +package kyber + +import ( + "crypto/cipher" +) + +// Scalar represents a scalar value by which +// a Point (group element) may be encrypted to produce another Point. +// This is an exponent in DSA-style groups, +// in which security is based on the Discrete Logarithm assumption, +// and a scalar multiplier in elliptic curve groups. +type Scalar interface { + Marshaling + + // Equality test for two Scalars derived from the same Group. + Equal(s2 Scalar) bool + + // Set sets the receiver equal to another Scalar a. + Set(a Scalar) Scalar + + // Clone creates a new Scalar with the same value. + Clone() Scalar + + // SetInt64 sets the receiver to a small integer value. + SetInt64(v int64) Scalar + + // Set to the additive identity (0). + Zero() Scalar + + // Set to the modular sum of scalars a and b. + Add(a, b Scalar) Scalar + + // Set to the modular difference a - b. + Sub(a, b Scalar) Scalar + + // Set to the modular negation of scalar a. + Neg(a Scalar) Scalar + + // Set to the multiplicative identity (1). + One() Scalar + + // Set to the modular product of scalars a and b. + Mul(a, b Scalar) Scalar + + // Set to the modular division of scalar a by scalar b. + Div(a, b Scalar) Scalar + + // Set to the modular inverse of scalar a. + Inv(a Scalar) Scalar + + // Set to a fresh random or pseudo-random scalar. + Pick(rand cipher.Stream) Scalar + + // SetBytes sets the scalar from a byte-slice, + // reducing if necessary to the appropriate modulus. + // The endianess of the byte-slice is determined by the + // implementation. + SetBytes([]byte) Scalar +} + +// Point represents an element of a public-key cryptographic Group. +// For example, +// this is a number modulo the prime P in a DSA-style Schnorr group, +// or an (x, y) point on an elliptic curve. +// A Point can contain a Diffie-Hellman public key, an ElGamal ciphertext, etc. +type Point interface { + Marshaling + + // Equality test for two Points derived from the same Group. + Equal(s2 Point) bool + + // Null sets the receiver to the neutral identity element. + Null() Point + + // Base sets the receiver to this group's standard base point. + Base() Point + + // Pick sets the receiver to a fresh random or pseudo-random Point. + Pick(rand cipher.Stream) Point + + // Set sets the receiver equal to another Point p. + Set(p Point) Point + + // Clone clones the underlying point. + Clone() Point + + // Maximum number of bytes that can be embedded in a single + // group element via Pick(). + EmbedLen() int + + // Embed encodes a limited amount of specified data in the + // Point, using r as a source of cryptographically secure + // random data. Implementations only embed the first EmbedLen + // bytes of the given data. + Embed(data []byte, r cipher.Stream) Point + + // Extract data embedded in a point chosen via Embed(). + // Returns an error if doesn't represent valid embedded data. + Data() ([]byte, error) + + // Add points so that their scalars add homomorphically. + Add(a, b Point) Point + + // Subtract points so that their scalars subtract homomorphically. + Sub(a, b Point) Point + + // Set to the negation of point a. + Neg(a Point) Point + + // Multiply point p by the scalar s. + // If p == nil, multiply with the standard base point Base(). + Mul(s Scalar, p Point) Point +} + +// AllowsVarTime allows callers to determine if a given kyber.Scalar +// or kyber.Point supports opting-in to variable time operations. If +// an object implements AllowsVarTime, then the caller can use +// AllowVarTime(true) in order to allow variable time operations on +// that object until AllowVarTime(false) is called. Variable time +// operations may be faster, but also risk leaking information via a +// timing side channel. Thus they are only safe to use on public +// Scalars and Points, never on secret ones. +type AllowsVarTime interface { + AllowVarTime(bool) +} + +// Group interface represents a mathematical group +// usable for Diffie-Hellman key exchange, ElGamal encryption, +// and the related body of public-key cryptographic algorithms +// and zero-knowledge proof methods. +// The Group interface is designed in particular to be a generic front-end +// to both traditional DSA-style modular arithmetic groups +// and ECDSA-style elliptic curves: +// the caller of this interface's methods +// need not know or care which specific mathematical construction +// underlies the interface. +// +// The Group interface is essentially just a "constructor" interface +// enabling the caller to generate the two particular types of objects +// relevant to DSA-style public-key cryptography; +// we call these objects Points and Scalars. +// The caller must explicitly initialize or set a new Point or Scalar object +// to some value before using it as an input to some other operation +// involving Point and/or Scalar objects. +// For example, to compare a point P against the neutral (identity) element, +// you might use P.Equal(suite.Point().Null()), +// but not just P.Equal(suite.Point()). +// +// It is expected that any implementation of this interface +// should satisfy suitable hardness assumptions for the applicable group: +// e.g., that it is cryptographically hard for an adversary to +// take an encrypted Point and the known generator it was based on, +// and derive the Scalar with which the Point was encrypted. +// Any implementation is also expected to satisfy +// the standard homomorphism properties that Diffie-Hellman +// and the associated body of public-key cryptography are based on. +type Group interface { + String() string + + ScalarLen() int // Max length of scalars in bytes + Scalar() Scalar // Create new scalar + + PointLen() int // Max length of point in bytes + Point() Point // Create new point +} diff --git a/kyber/group/curve25519/basic.go b/kyber/group/curve25519/basic.go new file mode 100644 index 0000000000..9eefb431ea --- /dev/null +++ b/kyber/group/curve25519/basic.go @@ -0,0 +1,213 @@ +// +build experimental + +package curve25519 + +import ( + "crypto/cipher" + "io" + "math/big" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/internal/marshalling" + "go.dedis.ch/kyber/v3/group/mod" +) + +type basicPoint struct { + x, y mod.Int + c *BasicCurve +} + +func (P *basicPoint) initXY(x, y *big.Int, c kyber.Group) { + P.c = c.(*BasicCurve) + P.x.Init(x, &P.c.P) + P.y.Init(y, &P.c.P) +} + +func (P *basicPoint) getXY() (x, y *mod.Int) { + return &P.x, &P.y +} + +func (P *basicPoint) String() string { + return P.c.pointString(&P.x, &P.y) +} + +// coord creates a new ModInt representing a coordinate on this curve, +// with a given int64 integer value for constant-initialization convenience. +func (P *basicPoint) coord(v int64) *mod.Int { + return mod.NewInt64(v, &P.c.P) +} + +func (P *basicPoint) MarshalSize() int { + return (P.y.M.BitLen() + 7 + 1) / 8 +} + +// MarshalBinary encodew an Edwards curve point. +func (P *basicPoint) MarshalBinary() ([]byte, error) { + return P.c.encodePoint(&P.x, &P.y), nil +} + +// UnmarshalBinary decodes an Edwards curve point. +func (P *basicPoint) UnmarshalBinary(b []byte) error { + return P.c.decodePoint(b, &P.x, &P.y) +} + +func (P *basicPoint) MarshalTo(w io.Writer) (int, error) { + return marshalling.PointMarshalTo(P, w) +} + +func (P *basicPoint) UnmarshalFrom(r io.Reader) (int, error) { + return marshalling.PointUnmarshalFrom(P, r) +} + +// Equal tests for two Points on the same curve +func (P *basicPoint) Equal(P2 kyber.Point) bool { + E2 := P2.(*basicPoint) + return P.x.Equal(&E2.x) && P.y.Equal(&E2.y) +} + +// Set point to be equal to P2. +func (P *basicPoint) Set(P2 kyber.Point) kyber.Point { + E2 := P2.(*basicPoint) + P.c = E2.c + P.x.Set(&E2.x) + P.y.Set(&E2.y) + return P +} + +// Clone returns the given point +func (P *basicPoint) Clone() kyber.Point { + p2 := new(basicPoint) + p2.Set(P) + return p2 +} + +// Null sets to the neutral element, which is (0,1) for twisted Edwards curves. +func (P *basicPoint) Null() kyber.Point { + P.Set(&P.c.null) + return P +} + +// Base sets to the standard base point for this curve +func (P *basicPoint) Base() kyber.Point { + P.Set(&P.c.base) + return P +} + +func (P *basicPoint) EmbedLen() int { + return P.c.embedLen() +} + +func (P *basicPoint) Embed(data []byte, rand cipher.Stream) kyber.Point { + P.c.embed(P, data, rand) + return P +} + +func (P *basicPoint) Pick(rand cipher.Stream) kyber.Point { + return P.Embed(nil, rand) +} + +// Data extracts embedded data from a point group element +func (P *basicPoint) Data() ([]byte, error) { + return P.c.data(&P.x, &P.y) +} + +// Add two points using the basic unified addition laws for Edwards curves: +// +// x' = ((x1*y2 + x2*y1) / (1 + d*x1*x2*y1*y2)) +// y' = ((y1*y2 - a*x1*x2) / (1 - d*x1*x2*y1*y2)) +// +func (P *basicPoint) Add(P1, P2 kyber.Point) kyber.Point { + E1 := P1.(*basicPoint) + E2 := P2.(*basicPoint) + x1, y1 := E1.x, E1.y + x2, y2 := E2.x, E2.y + + var t1, t2, dm, nx, dx, ny, dy mod.Int + + // Reused part of denominator: dm = d*x1*x2*y1*y2 + dm.Mul(&P.c.d, &x1).Mul(&dm, &x2).Mul(&dm, &y1).Mul(&dm, &y2) + + // x' numerator/denominator + nx.Add(t1.Mul(&x1, &y2), t2.Mul(&x2, &y1)) + dx.Add(&P.c.one, &dm) + + // y' numerator/denominator + ny.Sub(t1.Mul(&y1, &y2), t2.Mul(&x1, &x2).Mul(&P.c.a, &t2)) + dy.Sub(&P.c.one, &dm) + + // result point + P.x.Div(&nx, &dx) + P.y.Div(&ny, &dy) + return P +} + +// Point doubling, which for Edwards curves can be accomplished +// simply by adding a point to itself (no exceptions for equal input points). +func (P *basicPoint) double() kyber.Point { + return P.Add(P, P) +} + +// Subtract points so that their scalars subtract homomorphically +func (P *basicPoint) Sub(A, B kyber.Point) kyber.Point { + var nB basicPoint + return P.Add(A, nB.Neg(B)) +} + +// Find the negative of point A. +// For Edwards curves, the negative of (x,y) is (-x,y). +func (P *basicPoint) Neg(A kyber.Point) kyber.Point { + E := A.(*basicPoint) + P.c = E.c + P.x.Neg(&E.x) + P.y.Set(&E.y) + return P +} + +// Multiply point p by scalar s using the repeated doubling method. +func (P *basicPoint) Mul(s kyber.Scalar, G kyber.Point) kyber.Point { + v := s.(*mod.Int).V + if G == nil { + return P.Base().Mul(s, P) + } + T := P + if G == P { // Must use temporary in case G == P + T = &basicPoint{} + } + T.Set(&P.c.null) // Initialize to identity element (0,1) + for i := v.BitLen() - 1; i >= 0; i-- { + T.double() + if v.Bit(i) != 0 { + T.Add(T, G) + } + } + if T != P { + P.Set(T) + } + return P +} + +// Basic unoptimized reference implementation of Twisted Edwards curves. +// This reference implementation is mainly intended for testing, debugging, +// and instructional uses, and not for production use. +// The projective coordinates implementation (ProjectiveCurve) +// is just as general and much faster. +// +type BasicCurve struct { + curve // generic Edwards curve functionality + null basicPoint // Neutral/identity point (0,1) + base basicPoint // Standard base point +} + +// Create a new Point on this curve. +func (c *BasicCurve) Point() kyber.Point { + P := new(basicPoint) + P.c = c + P.Set(&c.null) + return P +} + +// Initialize the curve with given parameters. +func (c *BasicCurve) Init(p *Param, fullGroup bool) *BasicCurve { + c.curve.init(c, p, fullGroup, &c.null, &c.base) + return c +} diff --git a/kyber/group/curve25519/basic_test.go b/kyber/group/curve25519/basic_test.go new file mode 100644 index 0000000000..7667de15a2 --- /dev/null +++ b/kyber/group/curve25519/basic_test.go @@ -0,0 +1,72 @@ +// +build experimental + +package curve25519 + +import ( + "testing" + + "go.dedis.ch/kyber/v3/util/test" +) + +// Test the basic implementation of the Ed25519 curve. + +func TestBasic25519(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } else { + test.GroupTest(t, new(BasicCurve).Init(Param25519(), false)) + } +} + +// Test ProjectiveCurve versus BasicCurve implementations + +func TestCompareBasicProjective25519(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } else { + test.CompareGroups(t, testSuite.XOF, + new(BasicCurve).Init(Param25519(), false), + new(ProjectiveCurve).Init(Param25519(), false)) + } +} + +func TestCompareBasicProjectiveE382(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } else { + test.CompareGroups(t, testSuite.XOF, + new(BasicCurve).Init(ParamE382(), false), + new(ProjectiveCurve).Init(ParamE382(), false)) + } +} + +func TestCompareBasicProjective41417(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } else { + test.CompareGroups(t, testSuite.XOF, + new(BasicCurve).Init(Param41417(), false), + new(ProjectiveCurve).Init(Param41417(), false)) + } +} + +func TestCompareBasicProjectiveE521(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } else { + test.CompareGroups(t, testSuite.XOF, + new(BasicCurve).Init(ParamE521(), false), + new(ProjectiveCurve).Init(ParamE521(), false)) + } +} + +// Benchmark contrasting implementations of the Ed25519 curve + +var basicBench = test.NewGroupBench(new(BasicCurve).Init(Param25519(), false)) + +func BenchmarkPointAddBasic(b *testing.B) { basicBench.PointAdd(b.N) } +func BenchmarkPointMulBasic(b *testing.B) { basicBench.PointMul(b.N) } +func BenchmarkPointBaseMulBasic(b *testing.B) { basicBench.PointBaseMul(b.N) } +func BenchmarkPointEncodeBasic(b *testing.B) { basicBench.PointEncode(b.N) } +func BenchmarkPointDecodeBasic(b *testing.B) { basicBench.PointDecode(b.N) } +func BenchmarkPointPickBasic(b *testing.B) { basicBench.PointPick(b.N) } diff --git a/kyber/group/curve25519/curve.go b/kyber/group/curve25519/curve.go new file mode 100644 index 0000000000..4333cf92db --- /dev/null +++ b/kyber/group/curve25519/curve.go @@ -0,0 +1,396 @@ +package curve25519 + +import ( + "crypto/cipher" + "crypto/sha512" + "errors" + "fmt" + "math/big" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/mod" + "go.dedis.ch/kyber/v3/util/random" +) + +var zero = big.NewInt(0) +var one = big.NewInt(1) + +// Extension of Point interface for elliptic curve X,Y coordinate access +type point interface { + kyber.Point + + initXY(x, y *big.Int, curve kyber.Group) + + getXY() (x, y *mod.Int) +} + +// Generic "kyber.base class" for Edwards curves, +// embodying functionality independent of internal Point representation. +type curve struct { + self kyber.Group // "Self pointer" for derived class + Param // Twisted Edwards curve parameters + zero, one mod.Int // Constant ModInts with correct modulus + a, d mod.Int // Curve equation parameters as ModInts + full bool // True if we're using the full group + + order mod.Int // Order of appropriate subgroup as a ModInt + cofact mod.Int // Group's cofactor as a ModInt + + null kyber.Point // Identity point for this group +} + +func (c *curve) String() string { + if c.full { + return c.Param.String() + "-full" + } + return c.Param.String() +} + +func (c *curve) IsPrimeOrder() bool { + return !c.full +} + +// Returns the size in bytes of an encoded Scalar for this curve. +func (c *curve) ScalarLen() int { + return (c.order.V.BitLen() + 7) / 8 +} + +// Create a new Scalar for this curve. +func (c *curve) Scalar() kyber.Scalar { + return mod.NewInt64(0, &c.order.V) +} + +// Returns the size in bytes of an encoded Point on this curve. +// Uses compressed representation consisting of the y-coordinate +// and only the sign bit of the x-coordinate. +func (c *curve) PointLen() int { + return (c.P.BitLen() + 7 + 1) / 8 +} + +// NewKey returns a formatted curve25519 key (avoiding subgroup attack by requiring +// it to be a multiple of 8). NewKey implements the kyber/util/key.Generator interface. +func (c *curve) NewKey(stream cipher.Stream) kyber.Scalar { + var buffer [32]byte + random.Bytes(buffer[:], stream) + scalar := sha512.Sum512(buffer[:]) + scalar[0] &= 248 + scalar[31] &= 127 + scalar[31] |= 64 + + secret := c.Scalar().SetBytes(scalar[:32]) + return secret +} + +// Initialize a twisted Edwards curve with given parameters. +// Caller passes pointers to null and base point prototypes to be initialized. +func (c *curve) init(self kyber.Group, p *Param, fullGroup bool, + null, base point) *curve { + c.self = self + c.Param = *p + c.full = fullGroup + c.null = null + + // Edwards curve parameters as ModInts for convenience + c.a.Init(&p.A, &p.P) + c.d.Init(&p.D, &p.P) + + // Cofactor + c.cofact.Init64(int64(p.R), &c.P) + + // Determine the modulus for scalars on this curve. + // Note that we do NOT initialize c.order with Init(), + // as that would normalize to the modulus, resulting in zero. + // Just to be sure it's never used, we leave c.order.M set to nil. + // We want it to be in a ModInt so we can pass it to P.Mul(), + // but the scalar's modulus isn't needed for point multiplication. + if fullGroup { + // Scalar modulus is prime-order times the ccofactor + c.order.V.SetInt64(int64(p.R)).Mul(&c.order.V, &p.Q) + } else { + c.order.V.Set(&p.Q) // Prime-order subgroup + } + + // Useful ModInt constants for this curve + c.zero.Init64(0, &c.P) + c.one.Init64(1, &c.P) + + // Identity element is (0,1) + null.initXY(zero, one, self) + + // Base point B + var bx, by *big.Int + if !fullGroup { + bx, by = &p.PBX, &p.PBY + } else { + bx, by = &p.FBX, &p.FBY + base.initXY(&p.FBX, &p.FBY, self) + } + if by.Sign() == 0 { + // No standard base point was defined, so pick one. + // Find the lowest-numbered y-coordinate that works. + //println("Picking base point:") + var x, y mod.Int + for y.Init64(2, &c.P); ; y.Add(&y, &c.one) { + if !c.solveForX(&x, &y) { + continue // try another y + } + if c.coordSign(&x) != 0 { + x.Neg(&x) // try positive x first + } + base.initXY(&x.V, &y.V, self) + if c.validPoint(base) { + break // got one + } + x.Neg(&x) // try -bx + if c.validPoint(base) { + break // got one + } + } + //println("BX: "+x.V.String()) + //println("BY: "+y.V.String()) + bx, by = &x.V, &y.V + } + base.initXY(bx, by, self) + + // Sanity checks + if !c.validPoint(null) { + panic("invalid identity point " + null.String()) + } + if !c.validPoint(base) { + panic("invalid base point " + base.String()) + } + + return c +} + +// Test the sign of an x or y coordinate. +// We use the least-significant bit of the coordinate as the sign bit. +func (c *curve) coordSign(i *mod.Int) uint { + return i.V.Bit(0) +} + +// Convert a point to string representation. +func (c *curve) pointString(x, y *mod.Int) string { + return fmt.Sprintf("(%s,%s)", x.String(), y.String()) +} + +// Encode an Edwards curve point. +// We use little-endian encoding for consistency with Ed25519. +func (c *curve) encodePoint(x, y *mod.Int) []byte { + + // Encode the y-coordinate + b, _ := y.MarshalBinary() + + // Encode the sign of the x-coordinate. + if y.M.BitLen()&7 == 0 { + // No unused bits at the top of y-coordinate encoding, + // so we must prepend a whole byte. + b = append(make([]byte, 1), b...) + } + if c.coordSign(x) != 0 { + b[0] |= 0x80 + } + + // Convert to little-endian + reverse(b, b) + return b +} + +// Decode an Edwards curve point into the given x,y coordinates. +// Returns an error if the input does not denote a valid curve point. +// Note that this does NOT check if the point is in the prime-order subgroup: +// an adversary could create an encoding denoting a point +// on the twist of the curve, or in a larger subgroup. +// However, the "safecurves" criteria (http://safecurves.cr.yp.to) +// ensure that none of these other subgroups are small +// other than the tiny ones represented by the cofactor; +// hence Diffie-Hellman exchange can be done without subgroup checking +// without exposing more than the least-significant bits of the scalar. +func (c *curve) decodePoint(bb []byte, x, y *mod.Int) error { + + // Convert from little-endian + //fmt.Printf("decoding:\n%s\n", hex.Dump(bb)) + b := make([]byte, len(bb)) + reverse(b, bb) + + // Extract the sign of the x-coordinate + xsign := uint(b[0] >> 7) + b[0] &^= 0x80 + + // Extract the y-coordinate + y.V.SetBytes(b) + y.M = &c.P + + // Compute the corresponding x-coordinate + if !c.solveForX(x, y) { + return errors.New("invalid elliptic curve point") + } + if c.coordSign(x) != xsign { + x.Neg(x) + } + + return nil +} + +// Given a y-coordinate, solve for the x-coordinate on the curve, +// using the characteristic equation rewritten as: +// +// x^2 = (1 - y^2)/(a - d*y^2) +// +// Returns true on success, +// false if there is no x-coordinate corresponding to the chosen y-coordinate. +// +func (c *curve) solveForX(x, y *mod.Int) bool { + var yy, t1, t2 mod.Int + + yy.Mul(y, y) // yy = y^2 + t1.Sub(&c.one, &yy) // t1 = 1 - y^-2 + t2.Mul(&c.d, &yy).Sub(&c.a, &t2) // t2 = a - d*y^2 + t2.Div(&t1, &t2) // t2 = x^2 + return x.Sqrt(&t2) // may fail if not a square +} + +// Test if a supposed point is on the curve, +// by checking the characteristic equation for Edwards curves: +// +// a*x^2 + y^2 = 1 + d*x^2*y^2 +// +func (c *curve) onCurve(x, y *mod.Int) bool { + var xx, yy, l, r mod.Int + + xx.Mul(x, x) // xx = x^2 + yy.Mul(y, y) // yy = y^2 + + l.Mul(&c.a, &xx).Add(&l, &yy) // l = a*x^2 + y^2 + r.Mul(&c.d, &xx).Mul(&r, &yy).Add(&c.one, &r) + // r = 1 + d*x^2*y^2 + return l.Equal(&r) +} + +// Sanity-check a point to ensure that it is on the curve +// and within the appropriate subgroup. +func (c *curve) validPoint(P point) bool { + + // Check on-curve + x, y := P.getXY() + if !c.onCurve(x, y) { + return false + } + + // Check in-subgroup by multiplying by subgroup order + Q := c.self.Point() + Q.Mul(&c.order, P) + if !Q.Equal(c.null) { + return false + } + + return true +} + +// Return number of bytes that can be embedded into points on this curve. +func (c *curve) embedLen() int { + // Reserve at least 8 most-significant bits for randomness, + // and the least-significant 8 bits for embedded data length. + // (Hopefully it's unlikely we'll need >=2048-bit curves soon.) + return (c.P.BitLen() - 8 - 8) / 8 +} + +// Pick a [pseudo-]random curve point with optional embedded data, +// filling in the point's x,y coordinates +func (c *curve) embed(P point, data []byte, rand cipher.Stream) { + + // How much data to embed? + dl := c.embedLen() + if dl > len(data) { + dl = len(data) + } + + // Retry until we find a valid point + var x, y mod.Int + var Q kyber.Point + for { + // Get random bits the size of a compressed Point encoding, + // in which the topmost bit is reserved for the x-coord sign. + l := c.PointLen() + b := make([]byte, l) + rand.XORKeyStream(b, b) // Interpret as little-endian + if data != nil { + b[0] = byte(dl) // Encode length in low 8 bits + copy(b[1:1+dl], data) // Copy in data to embed + } + reverse(b, b) // Convert to big-endian form + + xsign := b[0] >> 7 // save x-coordinate sign bit + b[0] &^= 0xff << uint(c.P.BitLen()&7) // clear high bits + + y.M = &c.P // set y-coordinate + y.SetBytes(b) + + if !c.solveForX(&x, &y) { // Corresponding x-coordinate? + continue // none, retry + } + + // Pick a random sign for the x-coordinate + if c.coordSign(&x) != uint(xsign) { + x.Neg(&x) + } + + // Initialize the point + P.initXY(&x.V, &y.V, c.self) + if c.full { + // If we're using the full group, + // we just need any point on the curve, so we're done. + return + } + + // We're using the prime-order subgroup, + // so we need to make sure the point is in that subgroup. + // If we're not trying to embed data, + // we can convert our point into one in the subgroup + // simply by multiplying it by the cofactor. + if data == nil { + P.Mul(&c.cofact, P) // multiply by cofactor + if P.Equal(c.null) { + continue // unlucky; try again + } + return + } + + // Since we need the point's y-coordinate to make sense, + // we must simply check if the point is in the subgroup + // and retry point generation until it is. + if Q == nil { + Q = c.self.Point() + } + Q.Mul(&c.order, P) + if Q.Equal(c.null) { + return + } + + // Keep trying... + } +} + +// Extract embedded data from a point group element, +// or an error if embedded data is invalid or not present. +func (c *curve) data(x, y *mod.Int) ([]byte, error) { + b := c.encodePoint(x, y) + dl := int(b[0]) + if dl > c.embedLen() { + return nil, errors.New("invalid embedded data length") + } + return b[1 : 1+dl], nil +} + +// reverse copies src into dst in byte-reversed order and returns dst, +// such that src[0] goes into dst[len-1] and vice versa. +// dst and src may be the same slice but otherwise must not overlap. +func reverse(dst, src []byte) []byte { + l := len(dst) + for i, j := 0, l-1; i < (l+1)/2; { + dst[i], dst[j] = src[j], src[i] + i++ + j-- + } + return dst +} diff --git a/kyber/group/curve25519/curve_test.go b/kyber/group/curve25519/curve_test.go new file mode 100644 index 0000000000..033274823e --- /dev/null +++ b/kyber/group/curve25519/curve_test.go @@ -0,0 +1,143 @@ +package curve25519 + +import ( + "testing" + + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/util/test" +) + +var testSuite = NewBlakeSHA256Curve25519(false) + +// Test each curve implementation of the Ed25519 curve. + +func TestProjective25519(t *testing.T) { + test.GroupTest(t, new(ProjectiveCurve).Init(Param25519(), false)) +} + +func TestExtended25519(t *testing.T) { + test.GroupTest(t, new(ExtendedCurve).Init(Param25519(), false)) +} + +func TestEd25519(t *testing.T) { + test.GroupTest(t, new(edwards25519.Curve)) +} + +// Test the Extended coordinates implementation of each curve. + +func Test1174(t *testing.T) { + test.GroupTest(t, new(ExtendedCurve).Init(Param1174(), false)) +} + +func Test25519(t *testing.T) { + test.GroupTest(t, new(ExtendedCurve).Init(Param25519(), false)) +} + +func TestE382(t *testing.T) { + test.GroupTest(t, new(ExtendedCurve).Init(ParamE382(), false)) +} + +func Test4147(t *testing.T) { + test.GroupTest(t, new(ExtendedCurve).Init(Param41417(), false)) +} + +func TestE521(t *testing.T) { + test.GroupTest(t, new(ExtendedCurve).Init(ParamE521(), false)) +} + +func TestSetBytesBE(t *testing.T) { + g := new(ExtendedCurve).Init(ParamE521(), false) + s := g.Scalar() + s.SetBytes([]byte{0, 1, 2, 3}) + // 010203 because initial 0 is trimmed in String(), and 03 (last byte of BE) ends up + // in the LSB of the bigint. + if s.String() != "010203" { + t.Fatal("unexpected result from String():", s.String()) + } +} + +// Test the full-group-order Extended coordinates versions of each curve +// for which a full-group-order base point is defined. + +func TestFullOrder1174(t *testing.T) { + test.GroupTest(t, new(ExtendedCurve).Init(Param1174(), true)) +} + +func TestFullOrder25519(t *testing.T) { + test.GroupTest(t, new(ExtendedCurve).Init(Param25519(), true)) +} + +func TestFullOrderE382(t *testing.T) { + test.GroupTest(t, new(ExtendedCurve).Init(ParamE382(), true)) +} + +func TestFullOrder4147(t *testing.T) { + test.GroupTest(t, new(ExtendedCurve).Init(Param41417(), true)) +} + +func TestFullOrderE521(t *testing.T) { + test.GroupTest(t, new(ExtendedCurve).Init(ParamE521(), true)) +} + +// Test ExtendedCurve versus ProjectiveCurve implementations + +func TestCompareProjectiveExtended25519(t *testing.T) { + test.CompareGroups(t, testSuite.XOF, + new(ProjectiveCurve).Init(Param25519(), false), + new(ExtendedCurve).Init(Param25519(), false)) +} + +func TestCompareProjectiveExtendedE382(t *testing.T) { + test.CompareGroups(t, testSuite.XOF, + new(ProjectiveCurve).Init(ParamE382(), false), + new(ExtendedCurve).Init(ParamE382(), false)) +} + +func TestCompareProjectiveExtended41417(t *testing.T) { + test.CompareGroups(t, testSuite.XOF, + new(ProjectiveCurve).Init(Param41417(), false), + new(ExtendedCurve).Init(Param41417(), false)) +} + +func TestCompareProjectiveExtendedE521(t *testing.T) { + test.CompareGroups(t, testSuite.XOF, + new(ProjectiveCurve).Init(ParamE521(), false), + new(ExtendedCurve).Init(ParamE521(), false)) +} + +// Test Ed25519 versus ExtendedCurve implementations of Curve25519. +func TestCompareEd25519(t *testing.T) { + test.CompareGroups(t, testSuite.XOF, + new(ExtendedCurve).Init(Param25519(), false), + new(edwards25519.Curve)) +} + +// Benchmark contrasting implementations of the Ed25519 curve + +var projBench = test.NewGroupBench(new(ProjectiveCurve).Init(Param25519(), false)) +var extBench = test.NewGroupBench(new(ExtendedCurve).Init(Param25519(), false)) +var optBench = test.NewGroupBench(new(edwards25519.Curve)) + +func BenchmarkPointAddProjective(b *testing.B) { projBench.PointAdd(b.N) } +func BenchmarkPointAddExtended(b *testing.B) { extBench.PointAdd(b.N) } +func BenchmarkPointAddOptimized(b *testing.B) { optBench.PointAdd(b.N) } + +func BenchmarkPointMulProjective(b *testing.B) { projBench.PointMul(b.N) } +func BenchmarkPointMulExtended(b *testing.B) { extBench.PointMul(b.N) } +func BenchmarkPointMulOptimized(b *testing.B) { optBench.PointMul(b.N) } + +func BenchmarkPointBaseMulProjective(b *testing.B) { projBench.PointBaseMul(b.N) } +func BenchmarkPointBaseMulExtended(b *testing.B) { extBench.PointBaseMul(b.N) } +func BenchmarkPointBaseMulOptimized(b *testing.B) { optBench.PointBaseMul(b.N) } + +func BenchmarkPointEncodeProjective(b *testing.B) { projBench.PointEncode(b.N) } +func BenchmarkPointEncodeExtended(b *testing.B) { extBench.PointEncode(b.N) } +func BenchmarkPointEncodeOptimized(b *testing.B) { optBench.PointEncode(b.N) } + +func BenchmarkPointDecodeProjective(b *testing.B) { projBench.PointDecode(b.N) } +func BenchmarkPointDecodeExtended(b *testing.B) { extBench.PointDecode(b.N) } +func BenchmarkPointDecodeOptimized(b *testing.B) { optBench.PointDecode(b.N) } + +func BenchmarkPointPickProjective(b *testing.B) { projBench.PointPick(b.N) } +func BenchmarkPointPickExtended(b *testing.B) { extBench.PointPick(b.N) } +func BenchmarkPointPickOptimized(b *testing.B) { optBench.PointPick(b.N) } diff --git a/kyber/group/curve25519/ext.go b/kyber/group/curve25519/ext.go new file mode 100644 index 0000000000..c3bd0d17a2 --- /dev/null +++ b/kyber/group/curve25519/ext.go @@ -0,0 +1,294 @@ +package curve25519 + +import ( + "crypto/cipher" + "encoding/hex" + "io" + "math/big" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/internal/marshalling" + "go.dedis.ch/kyber/v3/group/mod" +) + +type extPoint struct { + X, Y, Z, T mod.Int + c *ExtendedCurve +} + +func (P *extPoint) initXY(x, y *big.Int, c kyber.Group) { + P.c = c.(*ExtendedCurve) + P.X.Init(x, &P.c.P) + P.Y.Init(y, &P.c.P) + P.Z.Init64(1, &P.c.P) + P.T.Mul(&P.X, &P.Y) +} + +func (P *extPoint) getXY() (x, y *mod.Int) { + P.normalize() + return &P.X, &P.Y +} + +func (P *extPoint) String() string { + P.normalize() + //return P.c.pointString(&P.X,&P.Y) + buf, _ := P.MarshalBinary() + return hex.EncodeToString(buf) +} + +func (P *extPoint) MarshalSize() int { + return P.c.PointLen() +} + +func (P *extPoint) MarshalBinary() ([]byte, error) { + P.normalize() + return P.c.encodePoint(&P.X, &P.Y), nil +} + +func (P *extPoint) UnmarshalBinary(b []byte) error { + if err := P.c.decodePoint(b, &P.X, &P.Y); err != nil { + return err + } + P.Z.Init64(1, &P.c.P) + P.T.Mul(&P.X, &P.Y) + return nil +} + +func (P *extPoint) MarshalTo(w io.Writer) (int, error) { + return marshalling.PointMarshalTo(P, w) +} + +func (P *extPoint) UnmarshalFrom(r io.Reader) (int, error) { + return marshalling.PointUnmarshalFrom(P, r) +} + +// Equality test for two Points on the same curve. +// We can avoid inversions here because: +// +// (X1/Z1,Y1/Z1) == (X2/Z2,Y2/Z2) +// iff +// (X1*Z2,Y1*Z2) == (X2*Z1,Y2*Z1) +// +func (P *extPoint) Equal(CP2 kyber.Point) bool { + P2 := CP2.(*extPoint) + var t1, t2 mod.Int + xeq := t1.Mul(&P.X, &P2.Z).Equal(t2.Mul(&P2.X, &P.Z)) + yeq := t1.Mul(&P.Y, &P2.Z).Equal(t2.Mul(&P2.Y, &P.Z)) + return xeq && yeq +} + +func (P *extPoint) Set(CP2 kyber.Point) kyber.Point { + P2 := CP2.(*extPoint) + P.c = P2.c + P.X.Set(&P2.X) + P.Y.Set(&P2.Y) + P.Z.Set(&P2.Z) + P.T.Set(&P2.T) + return P +} + +func (P *extPoint) Clone() kyber.Point { + P2 := extPoint{} + P2.c = P.c + P2.X.Set(&P.X) + P2.Y.Set(&P.Y) + P2.Z.Set(&P.Z) + P2.T.Set(&P.T) + return &P2 +} + +func (P *extPoint) Null() kyber.Point { + P.Set(&P.c.null) + return P +} + +func (P *extPoint) Base() kyber.Point { + P.Set(&P.c.base) + return P +} + +func (P *extPoint) EmbedLen() int { + return P.c.embedLen() +} + +// Normalize the point's representation to Z=1. +func (P *extPoint) normalize() { + P.Z.Inv(&P.Z) + P.X.Mul(&P.X, &P.Z) + P.Y.Mul(&P.Y, &P.Z) + P.Z.V.SetInt64(1) + P.T.Mul(&P.X, &P.Y) +} + +// Check the validity of the T coordinate +func (P *extPoint) checkT() { + var t1, t2 mod.Int + if !t1.Mul(&P.X, &P.Y).Equal(t2.Mul(&P.Z, &P.T)) { + panic("oops") + } +} + +func (P *extPoint) Embed(data []byte, rand cipher.Stream) kyber.Point { + P.c.embed(P, data, rand) + return P +} + +func (P *extPoint) Pick(rand cipher.Stream) kyber.Point { + P.c.embed(P, nil, rand) + return P +} + +// Extract embedded data from a point group element +func (P *extPoint) Data() ([]byte, error) { + P.normalize() + return P.c.data(&P.X, &P.Y) +} + +// Add two points using optimized extended coordinate addition formulas. +func (P *extPoint) Add(CP1, CP2 kyber.Point) kyber.Point { + P1 := CP1.(*extPoint) + P2 := CP2.(*extPoint) + X1, Y1, Z1, T1 := &P1.X, &P1.Y, &P1.Z, &P1.T + X2, Y2, Z2, T2 := &P2.X, &P2.Y, &P2.Z, &P2.T + X3, Y3, Z3, T3 := &P.X, &P.Y, &P.Z, &P.T + var A, B, C, D, E, F, G, H mod.Int + + A.Mul(X1, X2) + B.Mul(Y1, Y2) + C.Mul(T1, T2).Mul(&C, &P.c.d) + D.Mul(Z1, Z2) + E.Add(X1, Y1).Mul(&E, F.Add(X2, Y2)).Sub(&E, &A).Sub(&E, &B) + F.Sub(&D, &C) + G.Add(&D, &C) + H.Mul(&P.c.a, &A).Sub(&B, &H) + X3.Mul(&E, &F) + Y3.Mul(&G, &H) + T3.Mul(&E, &H) + Z3.Mul(&F, &G) + return P +} + +// Subtract points. +func (P *extPoint) Sub(CP1, CP2 kyber.Point) kyber.Point { + P1 := CP1.(*extPoint) + P2 := CP2.(*extPoint) + X1, Y1, Z1, T1 := &P1.X, &P1.Y, &P1.Z, &P1.T + X2, Y2, Z2, T2 := &P2.X, &P2.Y, &P2.Z, &P2.T + X3, Y3, Z3, T3 := &P.X, &P.Y, &P.Z, &P.T + var A, B, C, D, E, F, G, H mod.Int + + A.Mul(X1, X2) + B.Mul(Y1, Y2) + C.Mul(T1, T2).Mul(&C, &P.c.d) + D.Mul(Z1, Z2) + E.Add(X1, Y1).Mul(&E, F.Sub(Y2, X2)).Add(&E, &A).Sub(&E, &B) + F.Add(&D, &C) + G.Sub(&D, &C) + H.Mul(&P.c.a, &A).Add(&B, &H) + X3.Mul(&E, &F) + Y3.Mul(&G, &H) + T3.Mul(&E, &H) + Z3.Mul(&F, &G) + return P +} + +// Find the negative of point A. +// For Edwards curves, the negative of (x,y) is (-x,y). +func (P *extPoint) Neg(CA kyber.Point) kyber.Point { + A := CA.(*extPoint) + P.c = A.c + P.X.Neg(&A.X) + P.Y.Set(&A.Y) + P.Z.Set(&A.Z) + P.T.Neg(&A.T) + return P +} + +// Optimized point doubling for use in scalar multiplication. +// Uses the formulae in section 3.3 of: +// https://www.iacr.org/archive/asiacrypt2008/53500329/53500329.pdf +func (P *extPoint) double() { + X1, Y1, Z1, T1 := &P.X, &P.Y, &P.Z, &P.T + var A, B, C, D, E, F, G, H mod.Int + + A.Mul(X1, X1) + B.Mul(Y1, Y1) + C.Mul(Z1, Z1).Add(&C, &C) + D.Mul(&P.c.a, &A) + E.Add(X1, Y1).Mul(&E, &E).Sub(&E, &A).Sub(&E, &B) + G.Add(&D, &B) + F.Sub(&G, &C) + H.Sub(&D, &B) + X1.Mul(&E, &F) + Y1.Mul(&G, &H) + T1.Mul(&E, &H) + Z1.Mul(&F, &G) +} + +// Multiply point p by scalar s using the repeated doubling method. +// +// Currently doesn't implement the optimization of +// switching between projective and extended coordinates during +// scalar multiplication. +// +func (P *extPoint) Mul(s kyber.Scalar, G kyber.Point) kyber.Point { + v := s.(*mod.Int).V + if G == nil { + return P.Base().Mul(s, P) + } + T := P + if G == P { // Must use temporary for in-place multiply + T = &extPoint{} + } + T.Set(&P.c.null) // Initialize to identity element (0,1) + for i := v.BitLen() - 1; i >= 0; i-- { + T.double() + if v.Bit(i) != 0 { + T.Add(T, G) + } + } + if T != P { + P.Set(T) + } + return P +} + +// ExtendedCurve implements Twisted Edwards curves +// using projective coordinate representation (X:Y:Z), +// satisfying the identities x = X/Z, y = Y/Z. +// This representation still supports all Twisted Edwards curves +// and avoids expensive modular inversions on the critical paths. +// Uses the projective arithmetic formulas in: +// http://cr.yp.to/newelliptic/newelliptic-20070906.pdf +// + +// ExtendedCurve implements Twisted Edwards curves +// using the Extended Coordinate representation specified in: +// Hisil et al, "Twisted Edwards Curves Revisited", +// http://eprint.iacr.org/2008/522 +// +// This implementation is designed to work with all Twisted Edwards curves, +// foregoing the further optimizations that are available for the +// special case with curve parameter a=-1. +// We leave the task of hyperoptimization to curve-specific implementations +// such as the ed25519 package. +// +type ExtendedCurve struct { + curve // generic Edwards curve functionality + null extPoint // Constant identity/null point (0,1) + base extPoint // Standard base point +} + +// Point creates a new Point on this curve. +func (c *ExtendedCurve) Point() kyber.Point { + P := new(extPoint) + P.c = c + //P.Set(&c.null) + return P +} + +// Init initializes the curve with given parameters. +func (c *ExtendedCurve) Init(p *Param, fullGroup bool) *ExtendedCurve { + c.curve.init(c, p, fullGroup, &c.null, &c.base) + return c +} diff --git a/kyber/group/curve25519/param.go b/kyber/group/curve25519/param.go new file mode 100644 index 0000000000..f59624e296 --- /dev/null +++ b/kyber/group/curve25519/param.go @@ -0,0 +1,159 @@ +// Package curve25519 contains several implementations of Twisted Edwards Curves, +// from general and unoptimized to highly specialized and optimized. +// +// Twisted Edwards curves are elliptic curves satisfying the equation: +// +// ax^2 + y^2 = c^2(1 + dx^2y^2) +// +// for some scalars c, d over some field K. We assume K is a (finite) prime field for a +// large prime p. We also assume c == 1 because all curves in the generalized form +// are isomorphic to curves having c == 1. +// +// For details see Bernstein et al, "Twisted Edwards Curves", http://eprint.iacr.org/2008/013.pdf +package curve25519 + +import ( + "math/big" + + "go.dedis.ch/kyber/v3/group/mod" +) + +// Param defines a Twisted Edwards curve (TEC). +type Param struct { + Name string // Name of curve + + P big.Int // Prime defining the underlying field + Q big.Int // Order of the prime-order base point + R int // Cofactor: Q*R is the total size of the curve + + A, D big.Int // Edwards curve equation parameters + + FBX, FBY big.Int // Standard base point for full group + PBX, PBY big.Int // Standard base point for prime-order subgroup + + Elligator1s big.Int // Optional s parameter for Elligator 1 + Elligator2u big.Int // Optional u parameter for Elligator 2 +} + +// Return the name of this curve. +func (p *Param) String() string { + return p.Name +} + +// Param1174 defines Curve1174, as specified in: +// Bernstein et al, "Elligator: Elliptic-curve points indistinguishable +// from uniform random strings" +// http://elligator.cr.yp.to/elligator-20130828.pdf +// +func Param1174() *Param { + var p Param + var mi mod.Int + + p.Name = "Curve1174" + p.P.SetBit(zero, 251, 1).Sub(&p.P, big.NewInt(9)) + p.Q.SetString("45330879683285730139092453152713398835", 10) + p.Q.Sub(&p.P, &p.Q).Div(&p.Q, big.NewInt(4)) + p.R = 4 + p.A.SetInt64(1) + p.D.SetInt64(-1174) + + // Full-group generator is (4/V,3/5) + mi.InitString("4", "19225777642111670230408712442205514783403012708409058383774613284963344096", 10, &p.P) + p.FBX.Set(&mi.V) + mi.InitString("3", "5", 10, &p.P) + p.FBY.Set(&mi.V) + + // Elligator1 parameter s for Curve1174 (Elligator paper section 4.1) + p.Elligator1s.SetString("1806494121122717992522804053500797229648438766985538871240722010849934886421", 10) + + return &p +} + +// Param25519 defines the Edwards version of Curve25519, as specified in: +// Bernstein et al, "High-speed high-security signatures", +// http://ed25519.cr.yp.to/ed25519-20110926.pdf +// +func Param25519() *Param { + var p Param + var qs big.Int + p.Name = "Curve25519" + p.P.SetBit(zero, 255, 1).Sub(&p.P, big.NewInt(19)) + qs.SetString("27742317777372353535851937790883648493", 10) + p.Q.SetBit(zero, 252, 1).Add(&p.Q, &qs) + p.R = 8 + p.A.SetInt64(-1).Add(&p.P, &p.A) + p.D.SetString("37095705934669439343138083508754565189542113879843219016388785533085940283555", 10) + + p.PBX.SetString("15112221349535400772501151409588531511454012693041857206046113283949847762202", 10) + p.PBY.SetString("46316835694926478169428394003475163141307993866256225615783033603165251855960", 10) + + // Non-square u for Elligator2 + p.Elligator2u.SetInt64(2) + + return &p +} + +// ParamE382 defines the E-382 curve specified in: +// Aranha et al, "A note on high-security general-purpose elliptic curves", +// http://eprint.iacr.org/2013/647.pdf +// +// and more recently in: +// +// "Additional Elliptic Curves for IETF protocols" +// http://tools.ietf.org/html/draft-ladd-safecurves-02 +// (this I-D is now expired) +func ParamE382() *Param { + var p Param + var qs big.Int + p.Name = "E-382" + p.P.SetBit(zero, 382, 1).Sub(&p.P, big.NewInt(105)) // p = 2^382-105 + qs.SetString("1030303207694556153926491950732314247062623204330168346855", 10) + p.Q.SetBit(zero, 380, 1).Sub(&p.Q, &qs) + p.R = 8 + p.A.SetInt64(1) + p.D.SetInt64(-67254) + p.PBX.SetString("3914921414754292646847594472454013487047137431784830634731377862923477302047857640522480241298429278603678181725699", 10) + p.PBY.SetString("17", 10) + return &p +} + +// Param41417 defines the Curve41417 curve, as specified in: +// Bernstein et al, "Curve41417: Karatsuba revisited", +// http://eprint.iacr.org/2014/526.pdf +func Param41417() *Param { + var p Param + var qs big.Int + p.Name = "Curve41417" + p.P.SetBit(zero, 414, 1).Sub(&p.P, big.NewInt(17)) + qs.SetString("33364140863755142520810177694098385178984727200411208589594759", 10) + p.Q.SetBit(zero, 411, 1).Sub(&p.Q, &qs) + p.R = 8 + p.A.SetInt64(1) + p.D.SetInt64(3617) + p.PBX.SetString("17319886477121189177719202498822615443556957307604340815256226171904769976866975908866528699294134494857887698432266169206165", 10) + p.PBY.SetString("34", 10) + return &p +} + +// ParamE521 defines the E-521 curve specified in: +// Aranha et al, "A note on high-security general-purpose elliptic curves", +// http://eprint.iacr.org/2013/647.pdf +// +// and more recently included in: +// "Additional Elliptic Curves for IETF protocols" +// http://tools.ietf.org/html/draft-ladd-safecurves-02 +// +func ParamE521() *Param { + var p Param + var qs big.Int + p.Name = "E-521" + p.P.SetBit(zero, 521, 1).Sub(&p.P, one) + qs.SetString("337554763258501705789107630418782636071904961214051226618635150085779108655765", 10) + p.Q.SetBit(zero, 519, 1).Sub(&p.Q, &qs) + p.R = 8 + p.A.SetInt64(1) + p.D.SetInt64(-376014) + p.PBX.SetString("1571054894184995387535939749894317568645297350402905821437625181152304994381188529632591196067604100772673927915114267193389905003276673749012051148356041324", 10) + p.PBY.SetString("12", 10) + return &p +} diff --git a/kyber/group/curve25519/proj.go b/kyber/group/curve25519/proj.go new file mode 100644 index 0000000000..4efee7f6ce --- /dev/null +++ b/kyber/group/curve25519/proj.go @@ -0,0 +1,262 @@ +package curve25519 + +import ( + "crypto/cipher" + "io" + "math/big" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/internal/marshalling" + "go.dedis.ch/kyber/v3/group/mod" +) + +type projPoint struct { + X, Y, Z mod.Int + c *ProjectiveCurve +} + +func (P *projPoint) initXY(x, y *big.Int, c kyber.Group) { + P.c = c.(*ProjectiveCurve) + P.X.Init(x, &P.c.P) + P.Y.Init(y, &P.c.P) + P.Z.Init64(1, &P.c.P) +} + +func (P *projPoint) getXY() (x, y *mod.Int) { + P.normalize() + return &P.X, &P.Y +} + +func (P *projPoint) String() string { + P.normalize() + return P.c.pointString(&P.X, &P.Y) +} + +func (P *projPoint) MarshalSize() int { + return P.c.PointLen() +} + +func (P *projPoint) MarshalBinary() ([]byte, error) { + P.normalize() + return P.c.encodePoint(&P.X, &P.Y), nil +} + +func (P *projPoint) UnmarshalBinary(b []byte) error { + P.Z.Init64(1, &P.c.P) + return P.c.decodePoint(b, &P.X, &P.Y) +} + +func (P *projPoint) MarshalTo(w io.Writer) (int, error) { + return marshalling.PointMarshalTo(P, w) +} + +func (P *projPoint) UnmarshalFrom(r io.Reader) (int, error) { + return marshalling.PointUnmarshalFrom(P, r) +} + +// Equality test for two Points on the same curve. +// We can avoid inversions here because: +// +// (X1/Z1,Y1/Z1) == (X2/Z2,Y2/Z2) +// iff +// (X1*Z2,Y1*Z2) == (X2*Z1,Y2*Z1) +// +func (P *projPoint) Equal(CP2 kyber.Point) bool { + P2 := CP2.(*projPoint) + var t1, t2 mod.Int + xeq := t1.Mul(&P.X, &P2.Z).Equal(t2.Mul(&P2.X, &P.Z)) + yeq := t1.Mul(&P.Y, &P2.Z).Equal(t2.Mul(&P2.Y, &P.Z)) + return xeq && yeq +} + +func (P *projPoint) Set(CP2 kyber.Point) kyber.Point { + P2 := CP2.(*projPoint) + P.c = P2.c + P.X.Set(&P2.X) + P.Y.Set(&P2.Y) + P.Z.Set(&P2.Z) + return P +} + +func (P *projPoint) Clone() kyber.Point { + P2 := projPoint{} + P2.c = P.c + P2.X.Set(&P.X) + P2.Y.Set(&P.Y) + P2.Z.Set(&P.Z) + return &P2 +} + +func (P *projPoint) Null() kyber.Point { + P.Set(&P.c.null) + return P +} + +func (P *projPoint) Base() kyber.Point { + P.Set(&P.c.base) + return P +} + +func (P *projPoint) EmbedLen() int { + return P.c.embedLen() +} + +// Normalize the point's representation to Z=1. +func (P *projPoint) normalize() { + P.Z.Inv(&P.Z) + P.X.Mul(&P.X, &P.Z) + P.Y.Mul(&P.Y, &P.Z) + P.Z.V.SetInt64(1) +} + +func (P *projPoint) Embed(data []byte, rand cipher.Stream) kyber.Point { + P.c.embed(P, data, rand) + return P +} + +func (P *projPoint) Pick(rand cipher.Stream) kyber.Point { + return P.Embed(nil, rand) +} + +// Extract embedded data from a point group element +func (P *projPoint) Data() ([]byte, error) { + P.normalize() + return P.c.data(&P.X, &P.Y) +} + +// Add two points using optimized projective coordinate addition formulas. +// Formulas taken from: +// +// http://eprint.iacr.org/2008/013.pdf +// https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html +// +func (P *projPoint) Add(CP1, CP2 kyber.Point) kyber.Point { + P1 := CP1.(*projPoint) + P2 := CP2.(*projPoint) + X1, Y1, Z1 := &P1.X, &P1.Y, &P1.Z + X2, Y2, Z2 := &P2.X, &P2.Y, &P2.Z + var A, B, C, D, E, F, G, X3, Y3, Z3 mod.Int + + A.Mul(Z1, Z2) + B.Mul(&A, &A) + C.Mul(X1, X2) + D.Mul(Y1, Y2) + E.Mul(&C, &D).Mul(&P.c.d, &E) + F.Sub(&B, &E) + G.Add(&B, &E) + X3.Add(X1, Y1).Mul(&X3, Z3.Add(X2, Y2)).Sub(&X3, &C).Sub(&X3, &D). + Mul(&F, &X3).Mul(&A, &X3) + Y3.Mul(&P.c.a, &C).Sub(&D, &Y3).Mul(&G, &Y3).Mul(&A, &Y3) + Z3.Mul(&F, &G) + + P.c = P1.c + P.X.Set(&X3) + P.Y.Set(&Y3) + P.Z.Set(&Z3) + return P +} + +// Subtract points so that their scalars subtract homomorphically +func (P *projPoint) Sub(CP1, CP2 kyber.Point) kyber.Point { + P1 := CP1.(*projPoint) + P2 := CP2.(*projPoint) + X1, Y1, Z1 := &P1.X, &P1.Y, &P1.Z + X2, Y2, Z2 := &P2.X, &P2.Y, &P2.Z + var A, B, C, D, E, F, G, X3, Y3, Z3 mod.Int + + A.Mul(Z1, Z2) + B.Mul(&A, &A) + C.Mul(X1, X2) + D.Mul(Y1, Y2) + E.Mul(&C, &D).Mul(&P.c.d, &E) + F.Add(&B, &E) + G.Sub(&B, &E) + X3.Add(X1, Y1).Mul(&X3, Z3.Sub(Y2, X2)).Add(&X3, &C).Sub(&X3, &D). + Mul(&F, &X3).Mul(&A, &X3) + Y3.Mul(&P.c.a, &C).Add(&D, &Y3).Mul(&G, &Y3).Mul(&A, &Y3) + Z3.Mul(&F, &G) + + P.c = P1.c + P.X.Set(&X3) + P.Y.Set(&Y3) + P.Z.Set(&Z3) + return P +} + +// Find the negative of point A. +// For Edwards curves, the negative of (x,y) is (-x,y). +func (P *projPoint) Neg(CA kyber.Point) kyber.Point { + A := CA.(*projPoint) + P.c = A.c + P.X.Neg(&A.X) + P.Y.Set(&A.Y) + P.Z.Set(&A.Z) + return P +} + +// Optimized point doubling for use in scalar multiplication. +func (P *projPoint) double() { + var B, C, D, E, F, H, J mod.Int + + B.Add(&P.X, &P.Y).Mul(&B, &B) + C.Mul(&P.X, &P.X) + D.Mul(&P.Y, &P.Y) + E.Mul(&P.c.a, &C) + F.Add(&E, &D) + H.Mul(&P.Z, &P.Z) + J.Add(&H, &H).Sub(&F, &J) + P.X.Sub(&B, &C).Sub(&P.X, &D).Mul(&P.X, &J) + P.Y.Sub(&E, &D).Mul(&F, &P.Y) + P.Z.Mul(&F, &J) +} + +// Multiply point p by scalar s using the repeated doubling method. +func (P *projPoint) Mul(s kyber.Scalar, G kyber.Point) kyber.Point { + v := s.(*mod.Int).V + if G == nil { + return P.Base().Mul(s, P) + } + T := P + if G == P { // Must use temporary for in-place multiply + T = &projPoint{} + } + T.Set(&P.c.null) // Initialize to identity element (0,1) + for i := v.BitLen() - 1; i >= 0; i-- { + T.double() + if v.Bit(i) != 0 { + T.Add(T, G) + } + } + if T != P { + P.Set(T) + } + return P +} + +// ProjectiveCurve implements Twisted Edwards curves +// using projective coordinate representation (X:Y:Z), +// satisfying the identities x = X/Z, y = Y/Z. +// This representation still supports all Twisted Edwards curves +// and avoids expensive modular inversions on the critical paths. +// Uses the projective arithmetic formulas in: +// http://cr.yp.to/newelliptic/newelliptic-20070906.pdf +// +type ProjectiveCurve struct { + curve // generic Edwards curve functionality + null projPoint // Constant identity/null point (0,1) + base projPoint // Standard base point +} + +// Point creates a new Point on this curve. +func (c *ProjectiveCurve) Point() kyber.Point { + P := new(projPoint) + P.c = c + //P.Set(&c.null) + return P +} + +// Init initializes the curve with given parameters. +func (c *ProjectiveCurve) Init(p *Param, fullGroup bool) *ProjectiveCurve { + c.curve.init(c, p, fullGroup, &c.null, &c.base) + return c +} diff --git a/kyber/group/curve25519/suite.go b/kyber/group/curve25519/suite.go new file mode 100644 index 0000000000..4b0249e1da --- /dev/null +++ b/kyber/group/curve25519/suite.go @@ -0,0 +1,63 @@ +package curve25519 + +import ( + "crypto/cipher" + "crypto/sha256" + "hash" + "io" + "reflect" + + "go.dedis.ch/fixbuf" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/internal/marshalling" + "go.dedis.ch/kyber/v3/util/random" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +// SuiteCurve25519 is the suite for the 25519 curve +type SuiteCurve25519 struct { + ProjectiveCurve +} + +// Hash returns the instance associated with the suite +func (s *SuiteCurve25519) Hash() hash.Hash { + return sha256.New() +} + +// XOF creates the XOF associated with the suite +func (s *SuiteCurve25519) XOF(seed []byte) kyber.XOF { + return blake2xb.New(seed) +} + +func (s *SuiteCurve25519) Read(r io.Reader, objs ...interface{}) error { + return fixbuf.Read(r, s, objs) +} + +func (s *SuiteCurve25519) Write(w io.Writer, objs ...interface{}) error { + return fixbuf.Write(w, objs) +} + +// New implements the kyber.encoding interface +func (s *SuiteCurve25519) New(t reflect.Type) interface{} { + return marshalling.GroupNew(s, t) +} + +// RandomStream returns a cipher.Stream that returns a key stream +// from crypto/rand. +func (s *SuiteCurve25519) RandomStream() cipher.Stream { + return random.New() +} + +// NewBlakeSHA256Curve25519 returns a cipher suite based on package +// go.dedis.ch/kyber/v3/xof/blake2xb, SHA-256, and Curve25519. +// +// If fullGroup is false, then the group is the prime-order subgroup. +// +// The scalars created by this group implement kyber.Scalar's SetBytes +// method, interpreting the bytes as a big-endian integer, so as to be +// compatible with the Go standard library's big.Int type. +func NewBlakeSHA256Curve25519(fullGroup bool) *SuiteCurve25519 { + suite := new(SuiteCurve25519) + suite.Init(Param25519(), fullGroup) + return suite +} diff --git a/ocs/edwards25519/LICENSE b/kyber/group/edwards25519/LICENSE similarity index 100% rename from ocs/edwards25519/LICENSE rename to kyber/group/edwards25519/LICENSE diff --git a/ocs/edwards25519/allowvt_test.go b/kyber/group/edwards25519/allowvt_test.go similarity index 100% rename from ocs/edwards25519/allowvt_test.go rename to kyber/group/edwards25519/allowvt_test.go diff --git a/ocs/edwards25519/const.go b/kyber/group/edwards25519/const.go similarity index 100% rename from ocs/edwards25519/const.go rename to kyber/group/edwards25519/const.go diff --git a/ocs/edwards25519/curve.go b/kyber/group/edwards25519/curve.go similarity index 100% rename from ocs/edwards25519/curve.go rename to kyber/group/edwards25519/curve.go diff --git a/ocs/edwards25519/curve_test.go b/kyber/group/edwards25519/curve_test.go similarity index 100% rename from ocs/edwards25519/curve_test.go rename to kyber/group/edwards25519/curve_test.go diff --git a/ocs/edwards25519/fe.go b/kyber/group/edwards25519/fe.go similarity index 100% rename from ocs/edwards25519/fe.go rename to kyber/group/edwards25519/fe.go diff --git a/ocs/edwards25519/ge.go b/kyber/group/edwards25519/ge.go similarity index 100% rename from ocs/edwards25519/ge.go rename to kyber/group/edwards25519/ge.go diff --git a/ocs/edwards25519/ge_mult_vartime.go b/kyber/group/edwards25519/ge_mult_vartime.go similarity index 100% rename from ocs/edwards25519/ge_mult_vartime.go rename to kyber/group/edwards25519/ge_mult_vartime.go diff --git a/ocs/edwards25519/marshal.go b/kyber/group/edwards25519/marshal.go similarity index 100% rename from ocs/edwards25519/marshal.go rename to kyber/group/edwards25519/marshal.go diff --git a/ocs/edwards25519/point.go b/kyber/group/edwards25519/point.go similarity index 100% rename from ocs/edwards25519/point.go rename to kyber/group/edwards25519/point.go diff --git a/ocs/edwards25519/point_test.go b/kyber/group/edwards25519/point_test.go similarity index 100% rename from ocs/edwards25519/point_test.go rename to kyber/group/edwards25519/point_test.go diff --git a/ocs/edwards25519/point_vartime.go b/kyber/group/edwards25519/point_vartime.go similarity index 100% rename from ocs/edwards25519/point_vartime.go rename to kyber/group/edwards25519/point_vartime.go diff --git a/ocs/edwards25519/scalar.go b/kyber/group/edwards25519/scalar.go similarity index 100% rename from ocs/edwards25519/scalar.go rename to kyber/group/edwards25519/scalar.go diff --git a/ocs/edwards25519/scalar_test.go b/kyber/group/edwards25519/scalar_test.go similarity index 100% rename from ocs/edwards25519/scalar_test.go rename to kyber/group/edwards25519/scalar_test.go diff --git a/ocs/edwards25519/suite.go b/kyber/group/edwards25519/suite.go similarity index 100% rename from ocs/edwards25519/suite.go rename to kyber/group/edwards25519/suite.go diff --git a/kyber/group/internal/marshalling/marshal.go b/kyber/group/internal/marshalling/marshal.go new file mode 100644 index 0000000000..457b328db2 --- /dev/null +++ b/kyber/group/internal/marshalling/marshal.go @@ -0,0 +1,83 @@ +// Package marshalling provides a common implementation of (un)marshalling method using Writer and Reader. +// +package marshalling + +import ( + "crypto/cipher" + "io" + "reflect" + + "go.dedis.ch/kyber/v3" +) + +// PointMarshalTo provides a generic implementation of Point.EncodeTo +// based on Point.Encode. +func PointMarshalTo(p kyber.Point, w io.Writer) (int, error) { + buf, err := p.MarshalBinary() + if err != nil { + return 0, err + } + return w.Write(buf) +} + +// PointUnmarshalFrom provides a generic implementation of Point.DecodeFrom, +// based on Point.Decode, or Point.Pick if r is a Cipher or cipher.Stream. +// The returned byte-count is valid only when decoding from a normal Reader, +// not when picking from a pseudorandom source. +func PointUnmarshalFrom(p kyber.Point, r io.Reader) (int, error) { + if strm, ok := r.(cipher.Stream); ok { + p.Pick(strm) + return -1, nil // no byte-count when picking randomly + } + buf := make([]byte, p.MarshalSize()) + n, err := io.ReadFull(r, buf) + if err != nil { + return n, err + } + return n, p.UnmarshalBinary(buf) +} + +// ScalarMarshalTo provides a generic implementation of Scalar.EncodeTo +// based on Scalar.Encode. +func ScalarMarshalTo(s kyber.Scalar, w io.Writer) (int, error) { + buf, err := s.MarshalBinary() + if err != nil { + return 0, err + } + return w.Write(buf) +} + +// ScalarUnmarshalFrom provides a generic implementation of Scalar.DecodeFrom, +// based on Scalar.Decode, or Scalar.Pick if r is a Cipher or cipher.Stream. +// The returned byte-count is valid only when decoding from a normal Reader, +// not when picking from a pseudorandom source. +func ScalarUnmarshalFrom(s kyber.Scalar, r io.Reader) (int, error) { + if strm, ok := r.(cipher.Stream); ok { + s.Pick(strm) + return -1, nil // no byte-count when picking randomly + } + buf := make([]byte, s.MarshalSize()) + n, err := io.ReadFull(r, buf) + if err != nil { + return n, err + } + return n, s.UnmarshalBinary(buf) +} + +// Not used other than for reflect.TypeOf() +var aScalar kyber.Scalar +var aPoint kyber.Point + +var tScalar = reflect.TypeOf(&aScalar).Elem() +var tPoint = reflect.TypeOf(&aPoint).Elem() + +// GroupNew is the Default implementation of reflective constructor for Group +func GroupNew(g kyber.Group, t reflect.Type) interface{} { + switch t { + case tScalar: + return g.Scalar() + case tPoint: + return g.Point() + } + return nil +} diff --git a/kyber/group/mod/int.go b/kyber/group/mod/int.go new file mode 100644 index 0000000000..ba898f2fdd --- /dev/null +++ b/kyber/group/mod/int.go @@ -0,0 +1,430 @@ +// Package mod contains a generic implementation of finite field arithmetic +// on integer fields with a constant modulus. +package mod + +import ( + "crypto/cipher" + "encoding/hex" + "errors" + "io" + "math/big" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/internal/marshalling" + "go.dedis.ch/kyber/v3/util/random" +) + +var one = big.NewInt(1) +var two = big.NewInt(2) +var marshalScalarID = [8]byte{'m', 'o', 'd', '.', 'i', 'n', 't', ' '} + +// ByteOrder denotes the endianness of the operation. +type ByteOrder bool + +const ( + // LittleEndian endianness + LittleEndian ByteOrder = true + // BigEndian endianness + BigEndian ByteOrder = false +) + +// Int is a generic implementation of finite field arithmetic +// on integer finite fields with a given constant modulus, +// built using Go's built-in big.Int package. +// Int satisfies the kyber.Scalar interface, +// and hence serves as a basic implementation of kyber.Scalar, +// e.g., representing discrete-log exponents of Schnorr groups +// or scalar multipliers for elliptic curves. +// +// Int offers an API similar to and compatible with big.Int, +// but "carries around" a pointer to the relevant modulus +// and automatically normalizes the value to that modulus +// after all arithmetic operations, simplifying modular arithmetic. +// Binary operations assume that the source(s) +// have the same modulus, but do not check this assumption. +// Unary and binary arithmetic operations may be performed on uninitialized +// target objects, and receive the modulus of the first operand. +// For efficiency the modulus field M is a pointer, +// whose target is assumed never to change. +type Int struct { + V big.Int // Integer value from 0 through M-1 + M *big.Int // Modulus for finite field arithmetic + BO ByteOrder // Endianness which will be used on input and output +} + +// NewInt creaters a new Int with a given big.Int and a big.Int modulus. +func NewInt(v *big.Int, m *big.Int) *Int { + return new(Int).Init(v, m) +} + +// NewInt64 creates a new Int with a given int64 value and big.Int modulus. +func NewInt64(v int64, M *big.Int) *Int { + return new(Int).Init64(v, M) +} + +// NewIntBytes creates a new Int with a given slice of bytes and a big.Int +// modulus. +func NewIntBytes(a []byte, m *big.Int, byteOrder ByteOrder) *Int { + return new(Int).InitBytes(a, m, byteOrder) +} + +// NewIntString creates a new Int with a given string and a big.Int modulus. +// The value is set to a rational fraction n/d in a given base. +func NewIntString(n, d string, base int, m *big.Int) *Int { + return new(Int).InitString(n, d, base, m) +} + +// Init a Int with a given big.Int value and modulus pointer. +// Note that the value is copied; the modulus is not. +func (i *Int) Init(V *big.Int, m *big.Int) *Int { + i.M = m + i.BO = BigEndian + i.V.Set(V).Mod(&i.V, m) + return i +} + +// Init64 creates an Int with an int64 value and big.Int modulus. +func (i *Int) Init64(v int64, m *big.Int) *Int { + i.M = m + i.BO = BigEndian + i.V.SetInt64(v).Mod(&i.V, m) + return i +} + +// InitBytes init the Int to a number represented in a big-endian byte string. +func (i *Int) InitBytes(a []byte, m *big.Int, byteOrder ByteOrder) *Int { + i.M = m + i.BO = byteOrder + i.SetBytes(a) + return i +} + +// InitString inits the Int to a rational fraction n/d +// specified with a pair of strings in a given base. +func (i *Int) InitString(n, d string, base int, m *big.Int) *Int { + i.M = m + i.BO = BigEndian + if _, succ := i.SetString(n, d, base); !succ { + panic("InitString: invalid fraction representation") + } + return i +} + +// Return the Int's integer value in hexadecimal string representation. +func (i *Int) String() string { + return hex.EncodeToString(i.V.Bytes()) +} + +// SetString sets the Int to a rational fraction n/d represented by a pair of strings. +// If d == "", then the denominator is taken to be 1. +// Returns (i,true) on success, or +// (nil,false) if either string fails to parse. +func (i *Int) SetString(n, d string, base int) (*Int, bool) { + if _, succ := i.V.SetString(n, base); !succ { + return nil, false + } + if d != "" { + var di Int + di.M = i.M + if _, succ := di.SetString(d, "", base); !succ { + return nil, false + } + i.Div(i, &di) + } + return i, true +} + +// Cmp compares two Ints for equality or inequality +func (i *Int) Cmp(s2 kyber.Scalar) int { + return i.V.Cmp(&s2.(*Int).V) +} + +// Equal returns true if the two Ints are equal +func (i *Int) Equal(s2 kyber.Scalar) bool { + return i.V.Cmp(&s2.(*Int).V) == 0 +} + +// Nonzero returns true if the integer value is nonzero. +func (i *Int) Nonzero() bool { + return i.V.Sign() != 0 +} + +// Set both value and modulus to be equal to another Int. +// Since this method copies the modulus as well, +// it may be used as an alternative to Init(). +func (i *Int) Set(a kyber.Scalar) kyber.Scalar { + ai := a.(*Int) + i.V.Set(&ai.V) + i.M = ai.M + return i +} + +// Clone returns a separate duplicate of this Int. +func (i *Int) Clone() kyber.Scalar { + ni := new(Int).Init(&i.V, i.M) + ni.BO = i.BO + return ni +} + +// Zero set the Int to the value 0. The modulus must already be initialized. +func (i *Int) Zero() kyber.Scalar { + i.V.SetInt64(0) + return i +} + +// One sets the Int to the value 1. The modulus must already be initialized. +func (i *Int) One() kyber.Scalar { + i.V.SetInt64(1) + return i +} + +// SetInt64 sets the Int to an arbitrary 64-bit "small integer" value. +// The modulus must already be initialized. +func (i *Int) SetInt64(v int64) kyber.Scalar { + i.V.SetInt64(v).Mod(&i.V, i.M) + return i +} + +// Int64 returns the int64 representation of the value. +// If the value is not representable in an int64 the result is undefined. +func (i *Int) Int64() int64 { + return i.V.Int64() +} + +// SetUint64 sets the Int to an arbitrary uint64 value. +// The modulus must already be initialized. +func (i *Int) SetUint64(v uint64) kyber.Scalar { + i.V.SetUint64(v).Mod(&i.V, i.M) + return i +} + +// Uint64 returns the uint64 representation of the value. +// If the value is not representable in an uint64 the result is undefined. +func (i *Int) Uint64() uint64 { + return i.V.Uint64() +} + +// Add sets the target to a + b mod M, where M is a's modulus.. +func (i *Int) Add(a, b kyber.Scalar) kyber.Scalar { + ai := a.(*Int) + bi := b.(*Int) + i.M = ai.M + i.V.Add(&ai.V, &bi.V).Mod(&i.V, i.M) + return i +} + +// Sub sets the target to a - b mod M. +// Target receives a's modulus. +func (i *Int) Sub(a, b kyber.Scalar) kyber.Scalar { + ai := a.(*Int) + bi := b.(*Int) + i.M = ai.M + i.V.Sub(&ai.V, &bi.V).Mod(&i.V, i.M) + return i +} + +// Neg sets the target to -a mod M. +func (i *Int) Neg(a kyber.Scalar) kyber.Scalar { + ai := a.(*Int) + i.M = ai.M + if ai.V.Sign() > 0 { + i.V.Sub(i.M, &ai.V) + } else { + i.V.SetUint64(0) + } + return i +} + +// Mul sets the target to a * b mod M. +// Target receives a's modulus. +func (i *Int) Mul(a, b kyber.Scalar) kyber.Scalar { + ai := a.(*Int) + bi := b.(*Int) + i.M = ai.M + i.V.Mul(&ai.V, &bi.V).Mod(&i.V, i.M) + return i +} + +// Div sets the target to a * b^-1 mod M, where b^-1 is the modular inverse of b. +func (i *Int) Div(a, b kyber.Scalar) kyber.Scalar { + ai := a.(*Int) + bi := b.(*Int) + var t big.Int + i.M = ai.M + i.V.Mul(&ai.V, t.ModInverse(&bi.V, i.M)) + i.V.Mod(&i.V, i.M) + return i +} + +// Inv sets the target to the modular inverse of a with respect to modulus M. +func (i *Int) Inv(a kyber.Scalar) kyber.Scalar { + ai := a.(*Int) + i.M = ai.M + i.V.ModInverse(&a.(*Int).V, i.M) + return i +} + +// Exp sets the target to a^e mod M, +// where e is an arbitrary big.Int exponent (not necessarily 0 <= e < M). +func (i *Int) Exp(a kyber.Scalar, e *big.Int) kyber.Scalar { + ai := a.(*Int) + i.M = ai.M + // to protect against golang/go#22830 + var tmp big.Int + tmp.Exp(&ai.V, e, i.M) + i.V = tmp + return i +} + +// Jacobi computes the Jacobi symbol of (a/M), which indicates whether a is +// zero (0), a positive square in M (1), or a non-square in M (-1). +func (i *Int) Jacobi(as kyber.Scalar) kyber.Scalar { + ai := as.(*Int) + i.M = ai.M + i.V.SetInt64(int64(big.Jacobi(&ai.V, i.M))) + return i +} + +// Sqrt computes some square root of a mod M of one exists. +// Assumes the modulus M is an odd prime. +// Returns true on success, false if input a is not a square. +func (i *Int) Sqrt(as kyber.Scalar) bool { + ai := as.(*Int) + out := i.V.ModSqrt(&ai.V, ai.M) + i.M = ai.M + return out != nil +} + +// Pick a [pseudo-]random integer modulo M +// using bits from the given stream cipher. +func (i *Int) Pick(rand cipher.Stream) kyber.Scalar { + i.V.Set(random.Int(i.M, rand)) + return i +} + +// MarshalSize returns the length in bytes of encoded integers with modulus M. +// The length of encoded Ints depends only on the size of the modulus, +// and not on the the value of the encoded integer, +// making the encoding is fixed-length for simplicity and security. +func (i *Int) MarshalSize() int { + return (i.M.BitLen() + 7) / 8 +} + +// MarshalBinary encodes the value of this Int into a byte-slice exactly Len() bytes long. +// It uses i's ByteOrder to determine which byte order to output. +func (i *Int) MarshalBinary() ([]byte, error) { + l := i.MarshalSize() + b := i.V.Bytes() // may be shorter than l + offset := l - len(b) + + if i.BO == LittleEndian { + return i.LittleEndian(l, l), nil + } + + if offset != 0 { + nb := make([]byte, l) + copy(nb[offset:], b) + b = nb + } + return b, nil +} + +// MarshalID returns a unique identifier for this type +func (i *Int) MarshalID() [8]byte { + return marshalScalarID +} + +// UnmarshalBinary tries to decode a Int from a byte-slice buffer. +// Returns an error if the buffer is not exactly Len() bytes long +// or if the contents of the buffer represents an out-of-range integer. +func (i *Int) UnmarshalBinary(buf []byte) error { + if len(buf) != i.MarshalSize() { + return errors.New("UnmarshalBinary: wrong size buffer") + } + // Still needed here because of the comparison with the modulo + if i.BO == LittleEndian { + buf = reverse(nil, buf) + } + i.V.SetBytes(buf) + if i.V.Cmp(i.M) >= 0 { + return errors.New("UnmarshalBinary: value out of range") + } + return nil +} + +// MarshalTo encodes this Int to the given Writer. +func (i *Int) MarshalTo(w io.Writer) (int, error) { + return marshalling.ScalarMarshalTo(i, w) +} + +// UnmarshalFrom tries to decode an Int from the given Reader. +func (i *Int) UnmarshalFrom(r io.Reader) (int, error) { + return marshalling.ScalarUnmarshalFrom(i, r) +} + +// BigEndian encodes the value of this Int into a big-endian byte-slice +// at least min bytes but no more than max bytes long. +// Panics if max != 0 and the Int cannot be represented in max bytes. +func (i *Int) BigEndian(min, max int) []byte { + act := i.MarshalSize() + pad, ofs := act, 0 + if pad < min { + pad, ofs = min, min-act + } + if max != 0 && pad > max { + panic("Int not representable in max bytes") + } + buf := make([]byte, pad) + copy(buf[ofs:], i.V.Bytes()) + return buf +} + +// SetBytes set the value value to a number represented +// by a byte string. +// Endianness depends on the endianess set in i. +func (i *Int) SetBytes(a []byte) kyber.Scalar { + var buff = a + if i.BO == LittleEndian { + buff = reverse(nil, a) + } + i.V.SetBytes(buff).Mod(&i.V, i.M) + return i +} + +// LittleEndian encodes the value of this Int into a little-endian byte-slice +// at least min bytes but no more than max bytes long. +// Panics if max != 0 and the Int cannot be represented in max bytes. +func (i *Int) LittleEndian(min, max int) []byte { + act := i.MarshalSize() + vBytes := i.V.Bytes() + vSize := len(vBytes) + if vSize < act { + act = vSize + } + pad := act + if pad < min { + pad = min + } + if max != 0 && pad > max { + panic("Int not representable in max bytes") + } + buf := make([]byte, pad) + reverse(buf[:act], vBytes) + return buf +} + +// reverse copies src into dst in byte-reversed order and returns dst, +// such that src[0] goes into dst[len-1] and vice versa. +// dst and src may be the same slice but otherwise must not overlap. +func reverse(dst, src []byte) []byte { + if dst == nil { + dst = make([]byte, len(src)) + } + l := len(dst) + for i, j := 0, l-1; i < (l+1)/2; { + dst[i], dst[j] = src[j], src[i] + i++ + j-- + } + return dst +} diff --git a/kyber/group/mod/int_test.go b/kyber/group/mod/int_test.go new file mode 100644 index 0000000000..472d1b62a1 --- /dev/null +++ b/kyber/group/mod/int_test.go @@ -0,0 +1,90 @@ +package mod + +import ( + "bytes" + "encoding/hex" + "math/big" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIntEndianness(t *testing.T) { + modulo := big.NewInt(65535) + var v int64 = 65500 + // Let's assume it is bigendian and test that + i := new(Int).Init64(v, modulo) + assert.Equal(t, i.BO, BigEndian) + + buff1, err := i.MarshalBinary() + assert.Nil(t, err) + i.BO = BigEndian + buff2, err := i.MarshalBinary() + assert.Nil(t, err) + assert.Equal(t, buff1, buff2) + + // Let's change endianness and check the result + i.BO = LittleEndian + buff3, err := i.MarshalBinary() + assert.NotEqual(t, buff2, buff3) + + // let's try LittleEndian function + buff4 := i.LittleEndian(0, 32) + assert.Equal(t, buff3, buff4) + // set endianess but using littleendian should not change anything + i.BO = BigEndian + assert.Equal(t, buff4, i.LittleEndian(0, 32)) + + // Try to reconstruct the int from the buffer + i = new(Int).Init64(v, modulo) + i2 := NewInt64(0, modulo) + buff, _ := i.MarshalBinary() + assert.Nil(t, i2.UnmarshalBinary(buff)) + assert.True(t, i.Equal(i2)) + + i.BO = LittleEndian + buff, _ = i.MarshalBinary() + i2.BO = LittleEndian + assert.Nil(t, i2.UnmarshalBinary(buff)) + assert.True(t, i.Equal(i2)) + + i2.BO = BigEndian + assert.Nil(t, i2.UnmarshalBinary(buff)) + assert.False(t, i.Equal(i2)) +} +func TestIntEndianBytes(t *testing.T) { + modulo, err := hex.DecodeString("1000") + moduloI := new(big.Int).SetBytes(modulo) + assert.Nil(t, err) + v, err := hex.DecodeString("10") + assert.Nil(t, err) + + i := new(Int).InitBytes(v, moduloI, BigEndian) + + assert.Equal(t, 2, i.MarshalSize()) + assert.NotPanics(t, func() { i.LittleEndian(2, 2) }) +} + +func TestInits(t *testing.T) { + i1 := NewInt64(int64(65500), big.NewInt(65535)) + i2 := NewInt(&i1.V, i1.M) + assert.True(t, i1.Equal(i2)) + b, _ := i1.MarshalBinary() + i3 := NewIntBytes(b, i1.M, BigEndian) + assert.True(t, i1.Equal(i3)) + i4 := NewIntString(i1.String(), "", 16, i1.M) + assert.True(t, i1.Equal(i4)) +} + +func TestIntClone(t *testing.T) { + moduloI := new(big.Int).SetBytes([]byte{0x10, 0}) + base := new(Int).InitBytes([]byte{0x10}, moduloI, BigEndian) + + clone := base.Clone() + clone.Add(clone, clone) + b1, _ := clone.MarshalBinary() + b2, _ := base.MarshalBinary() + if bytes.Equal(b1, b2) { + t.Error("Should not be equal") + } +} diff --git a/kyber/group/nist/curve.go b/kyber/group/nist/curve.go new file mode 100644 index 0000000000..6888d9fc03 --- /dev/null +++ b/kyber/group/nist/curve.go @@ -0,0 +1,266 @@ +package nist + +import ( + "crypto/cipher" + "crypto/elliptic" + "errors" + "io" + "math/big" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/internal/marshalling" + "go.dedis.ch/kyber/v3/group/mod" + "go.dedis.ch/kyber/v3/util/random" +) + +type curvePoint struct { + x, y *big.Int + c *curve +} + +func (p *curvePoint) String() string { + return "(" + p.x.String() + "," + p.y.String() + ")" +} + +func (p *curvePoint) Equal(p2 kyber.Point) bool { + cp2 := p2.(*curvePoint) + + // Make sure both coordinates are normalized. + // Apparently Go's elliptic curve code doesn't always ensure this. + M := p.c.p.P + p.x.Mod(p.x, M) + p.y.Mod(p.y, M) + cp2.x.Mod(cp2.x, M) + cp2.y.Mod(cp2.y, M) + + return p.x.Cmp(cp2.x) == 0 && p.y.Cmp(cp2.y) == 0 +} + +func (p *curvePoint) Null() kyber.Point { + p.x = new(big.Int).SetInt64(0) + p.y = new(big.Int).SetInt64(0) + return p +} + +func (p *curvePoint) Base() kyber.Point { + p.x = p.c.p.Gx + p.y = p.c.p.Gy + return p +} + +func (p *curvePoint) Valid() bool { + // The IsOnCurve function in Go's elliptic curve package + // doesn't consider the point-at-infinity to be "on the curve" + return p.c.IsOnCurve(p.x, p.y) || + (p.x.Sign() == 0 && p.y.Sign() == 0) +} + +// Try to generate a point on this curve from a chosen x-coordinate, +// with a random sign. +func (p *curvePoint) genPoint(x *big.Int, rand cipher.Stream) bool { + + // Compute the corresponding Y coordinate, if any + y2 := new(big.Int).Mul(x, x) + y2.Mul(y2, x) + threeX := new(big.Int).Lsh(x, 1) + threeX.Add(threeX, x) + y2.Sub(y2, threeX) + y2.Add(y2, p.c.p.B) + y2.Mod(y2, p.c.p.P) + y := p.c.sqrt(y2) + + // Pick a random sign for the y coordinate + b := make([]byte, 1) + rand.XORKeyStream(b, b) + if (b[0] & 0x80) != 0 { + y.Sub(p.c.p.P, y) + } + + // Check that it's a valid point + y2t := new(big.Int).Mul(y, y) + y2t.Mod(y2t, p.c.p.P) + if y2t.Cmp(y2) != 0 { + return false // Doesn't yield a valid point! + } + + p.x = x + p.y = y + return true +} + +func (p *curvePoint) EmbedLen() int { + // Reserve at least 8 most-significant bits for randomness, + // and the least-significant 8 bits for embedded data length. + // (Hopefully it's unlikely we'll need >=2048-bit curves soon.) + return (p.c.p.P.BitLen() - 8 - 8) / 8 +} + +func (p *curvePoint) Pick(rand cipher.Stream) kyber.Point { + return p.Embed(nil, rand) +} + +// Pick a curve point containing a variable amount of embedded data. +// Remaining bits comprising the point are chosen randomly. +func (p *curvePoint) Embed(data []byte, rand cipher.Stream) kyber.Point { + + l := p.c.coordLen() + dl := p.EmbedLen() + if dl > len(data) { + dl = len(data) + } + + for { + b := random.Bits(uint(p.c.p.P.BitLen()), false, rand) + if data != nil { + b[l-1] = byte(dl) // Encode length in low 8 bits + copy(b[l-dl-1:l-1], data) // Copy in data to embed + } + if p.genPoint(new(big.Int).SetBytes(b), rand) { + return p + } + } +} + +// Extract embedded data from a curve point +func (p *curvePoint) Data() ([]byte, error) { + b := p.x.Bytes() + l := p.c.coordLen() + if len(b) < l { // pad leading zero bytes if necessary + b = append(make([]byte, l-len(b)), b...) + } + dl := int(b[l-1]) + if dl > p.EmbedLen() { + return nil, errors.New("invalid embedded data length") + } + return b[l-dl-1 : l-1], nil +} + +func (p *curvePoint) Add(a, b kyber.Point) kyber.Point { + ca := a.(*curvePoint) + cb := b.(*curvePoint) + p.x, p.y = p.c.Add(ca.x, ca.y, cb.x, cb.y) + return p +} + +func (p *curvePoint) Sub(a, b kyber.Point) kyber.Point { + ca := a.(*curvePoint) + cb := b.(*curvePoint) + + cbn := p.c.Point().Neg(cb).(*curvePoint) + p.x, p.y = p.c.Add(ca.x, ca.y, cbn.x, cbn.y) + return p +} + +func (p *curvePoint) Neg(a kyber.Point) kyber.Point { + + s := p.c.Scalar().One() + s.Neg(s) + return p.Mul(s, a).(*curvePoint) +} + +func (p *curvePoint) Mul(s kyber.Scalar, b kyber.Point) kyber.Point { + cs := s.(*mod.Int) + if b != nil { + cb := b.(*curvePoint) + p.x, p.y = p.c.ScalarMult(cb.x, cb.y, cs.V.Bytes()) + } else { + p.x, p.y = p.c.ScalarBaseMult(cs.V.Bytes()) + } + return p +} + +func (p *curvePoint) MarshalSize() int { + coordlen := (p.c.Params().BitSize + 7) >> 3 + return 1 + 2*coordlen // uncompressed ANSI X9.62 representation +} + +func (p *curvePoint) MarshalBinary() ([]byte, error) { + return elliptic.Marshal(p.c, p.x, p.y), nil +} + +func (p *curvePoint) UnmarshalBinary(buf []byte) error { + // Check whether all bytes after first one are 0, so we + // just return the initial point. Read everything to + // prevent timing-leakage. + var c byte + for _, b := range buf[1:] { + c |= b + } + if c != 0 { + p.x, p.y = elliptic.Unmarshal(p.c, buf) + if p.x == nil || !p.Valid() { + return errors.New("invalid elliptic curve point") + } + } else { + // All bytes are 0, so we initialize x and y + p.x = big.NewInt(0) + p.y = big.NewInt(0) + } + return nil +} + +func (p *curvePoint) MarshalTo(w io.Writer) (int, error) { + return marshalling.PointMarshalTo(p, w) +} + +func (p *curvePoint) UnmarshalFrom(r io.Reader) (int, error) { + return marshalling.PointUnmarshalFrom(p, r) +} + +// interface for curve-specifc mathematical functions +type curveOps interface { + sqrt(y *big.Int) *big.Int +} + +// Curve is an implementation of the kyber.Group interface +// for NIST elliptic curves, built on Go's native elliptic curve library. +type curve struct { + elliptic.Curve + curveOps + p *elliptic.CurveParams +} + +// Return the number of bytes in the encoding of a Scalar for this curve. +func (c *curve) ScalarLen() int { return (c.p.N.BitLen() + 7) / 8 } + +// Create a Scalar associated with this curve. The scalars created by +// this package implement kyber.Scalar's SetBytes method, interpreting +// the bytes as a big-endian integer, so as to be compatible with the +// Go standard library's big.Int type. +func (c *curve) Scalar() kyber.Scalar { + return mod.NewInt64(0, c.p.N) +} + +// Number of bytes required to store one coordinate on this curve +func (c *curve) coordLen() int { + return (c.p.BitSize + 7) / 8 +} + +// Return the number of bytes in the encoding of a Point for this curve. +// Currently uses uncompressed ANSI X9.62 format with both X and Y coordinates; +// this could change. +func (c *curve) PointLen() int { + return 1 + 2*c.coordLen() // ANSI X9.62: 1 header byte plus 2 coords +} + +// Create a Point associated with this curve. +func (c *curve) Point() kyber.Point { + p := new(curvePoint) + p.c = c + return p +} + +func (p *curvePoint) Set(P kyber.Point) kyber.Point { + p.x = P.(*curvePoint).x + p.y = P.(*curvePoint).y + return p +} + +func (p *curvePoint) Clone() kyber.Point { + return &curvePoint{x: p.x, y: p.y, c: p.c} +} + +// Return the order of this curve: the prime N in the curve parameters. +func (c *curve) Order() *big.Int { + return c.p.N +} diff --git a/kyber/group/nist/doc.go b/kyber/group/nist/doc.go new file mode 100644 index 0000000000..baf872e118 --- /dev/null +++ b/kyber/group/nist/doc.go @@ -0,0 +1,3 @@ +// Package nist implements cryptographic groups and ciphersuites +// based on the NIST standards, using Go's built-in crypto library. +package nist diff --git a/kyber/group/nist/group_test.go b/kyber/group/nist/group_test.go new file mode 100644 index 0000000000..e60de41985 --- /dev/null +++ b/kyber/group/nist/group_test.go @@ -0,0 +1,46 @@ +package nist + +import ( + "testing" + + "go.dedis.ch/kyber/v3/util/test" +) + +var testQR512 = NewBlakeSHA256QR512() + +func TestQR512(t *testing.T) { test.SuiteTest(t, testQR512) } + +var testP256 = NewBlakeSHA256P256() + +func TestP256(t *testing.T) { test.SuiteTest(t, testP256) } + +func TestSetBytesBE(t *testing.T) { + s := testP256.Scalar() + s.SetBytes([]byte{0, 1, 2, 3}) + // 010203 because initial 0 is trimmed in String(), and 03 (last byte of BE) ends up + // in the LSB of the bigint. + if s.String() != "010203" { + t.Fatal("unexpected result from String():", s.String()) + } +} + +var benchP256 = test.NewGroupBench(testP256) + +func BenchmarkScalarAdd(b *testing.B) { benchP256.ScalarAdd(b.N) } +func BenchmarkScalarSub(b *testing.B) { benchP256.ScalarSub(b.N) } +func BenchmarkScalarNeg(b *testing.B) { benchP256.ScalarNeg(b.N) } +func BenchmarkScalarMul(b *testing.B) { benchP256.ScalarMul(b.N) } +func BenchmarkScalarDiv(b *testing.B) { benchP256.ScalarDiv(b.N) } +func BenchmarkScalarInv(b *testing.B) { benchP256.ScalarInv(b.N) } +func BenchmarkScalarPick(b *testing.B) { benchP256.ScalarPick(b.N) } +func BenchmarkScalarEncode(b *testing.B) { benchP256.ScalarEncode(b.N) } +func BenchmarkScalarDecode(b *testing.B) { benchP256.ScalarDecode(b.N) } + +func BenchmarkPointAdd(b *testing.B) { benchP256.PointAdd(b.N) } +func BenchmarkPointSub(b *testing.B) { benchP256.PointSub(b.N) } +func BenchmarkPointNeg(b *testing.B) { benchP256.PointNeg(b.N) } +func BenchmarkPointMul(b *testing.B) { benchP256.PointMul(b.N) } +func BenchmarkPointBaseMul(b *testing.B) { benchP256.PointBaseMul(b.N) } +func BenchmarkPointPick(b *testing.B) { benchP256.PointPick(b.N) } +func BenchmarkPointEncode(b *testing.B) { benchP256.PointEncode(b.N) } +func BenchmarkPointDecode(b *testing.B) { benchP256.PointDecode(b.N) } diff --git a/kyber/group/nist/p256.go b/kyber/group/nist/p256.go new file mode 100644 index 0000000000..f9c072386d --- /dev/null +++ b/kyber/group/nist/p256.go @@ -0,0 +1,76 @@ +package nist + +import ( + "crypto/elliptic" + "math/big" +) + +// P256 implements the kyber.Group interface +// for the NIST P-256 elliptic curve, +// based on Go's native elliptic curve library. +type p256 struct { + curve +} + +func (curve *p256) String() string { + return "P256" +} + +// Optimized modular square root for P-256 curve, from +// "Mathematical routines for the NIST prime elliptic curves" (April 2010) +func (curve *p256) sqrt(c *big.Int) *big.Int { + m := curve.p.P + + t1 := new(big.Int) + t1.Mul(c, c) + t1.Mul(t1, c) // t1 = c^(2^2-1) + + p2 := new(big.Int) + p2.SetBit(p2, 2, 1) + t2 := new(big.Int) + t2.Exp(t1, p2, m) + t2.Mul(t2, t1) // t2 = c^(2^4-1) + + p3 := new(big.Int) + p3.SetBit(p3, 4, 1) + t3 := new(big.Int) + t3.Exp(t2, p3, m) + t3.Mul(t3, t2) // t3 = c^(2^8-1) + + p4 := new(big.Int) + p4.SetBit(p4, 8, 1) + t4 := new(big.Int) + t4.Exp(t3, p4, m) + t4.Mul(t4, t3) // t4 = c^(2^16-1) + + p5 := new(big.Int) + p5.SetBit(p5, 16, 1) + r := new(big.Int) + r.Exp(t4, p5, m) + r.Mul(r, t4) // r = c^(2^32-1) + + p6 := new(big.Int) + p6.SetBit(p6, 32, 1) + r.Exp(r, p6, m) + r.Mul(r, c) // r = c^(2^64-2^32+1) + + p7 := new(big.Int) + p7.SetBit(p7, 96, 1) + r.Exp(r, p7, m) + r.Mul(r, c) // r = c^(2^160-2^128+2^96+1) + + p8 := new(big.Int) + p8.SetBit(p8, 94, 1) + r.Exp(r, p8, m) + + // r = c^(2^254-2^222+2^190+2^94) = sqrt(c) mod p256 + return r +} + +// Init initializes standard Curve instances +func (curve *p256) Init() curve { + curve.curve.Curve = elliptic.P256() + curve.p = curve.Params() + curve.curveOps = curve + return curve.curve +} diff --git a/kyber/group/nist/qrsuite.go b/kyber/group/nist/qrsuite.go new file mode 100644 index 0000000000..2b1fc91072 --- /dev/null +++ b/kyber/group/nist/qrsuite.go @@ -0,0 +1,67 @@ +package nist + +import ( + "crypto/cipher" + "crypto/sha256" + "hash" + "io" + "math/big" + "reflect" + + "go.dedis.ch/fixbuf" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/internal/marshalling" + "go.dedis.ch/kyber/v3/util/random" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +// QrSuite is a quadratic residue suite +type QrSuite struct { + ResidueGroup +} + +// Hash returns the instance associated with the suite +func (s QrSuite) Hash() hash.Hash { + return sha256.New() +} + +// XOF creates the XOF associated with the suite +func (s QrSuite) XOF(key []byte) kyber.XOF { + return blake2xb.New(key) +} + +// RandomStream returns a cipher.Stream that returns a key stream +// from crypto/rand. +func (s QrSuite) RandomStream() cipher.Stream { + return random.New() +} + +func (s *QrSuite) Read(r io.Reader, objs ...interface{}) error { + return fixbuf.Read(r, s, objs) +} + +func (s *QrSuite) Write(w io.Writer, objs ...interface{}) error { + return fixbuf.Write(w, objs) +} + +// New implements the kyber.encoding interface +func (s *QrSuite) New(t reflect.Type) interface{} { + return marshalling.GroupNew(s, t) +} + +// NewBlakeSHA256QR512 returns a cipher suite based on package +// go.dedis.ch/kyber/v3/xof/blake2xb, SHA-256, and a residue group of +// quadratic residues modulo a 512-bit prime. +// +// This group size should be used only for testing and experimentation. +// 512-bit DSA-style groups are no longer considered secure. +func NewBlakeSHA256QR512() *QrSuite { + p, _ := new(big.Int).SetString("10198267722357351868598076141027380280417188309231803909918464305012113541414604537422741096561285049775792035177041672305646773132014126091142862443826263", 10) + q, _ := new(big.Int).SetString("5099133861178675934299038070513690140208594154615901954959232152506056770707302268711370548280642524887896017588520836152823386566007063045571431221913131", 10) + r := new(big.Int).SetInt64(2) + g := new(big.Int).SetInt64(4) + + suite := new(QrSuite) + suite.SetParams(p, q, r, g) + return suite +} diff --git a/kyber/group/nist/residue.go b/kyber/group/nist/residue.go new file mode 100644 index 0000000000..27b845b070 --- /dev/null +++ b/kyber/group/nist/residue.go @@ -0,0 +1,314 @@ +package nist + +import ( + "crypto/cipher" + "crypto/dsa" + "errors" + "fmt" + "io" + "math/big" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/internal/marshalling" + "go.dedis.ch/kyber/v3/group/mod" + "go.dedis.ch/kyber/v3/util/random" +) + +var one = big.NewInt(1) +var two = big.NewInt(2) + +type residuePoint struct { + big.Int + g *ResidueGroup +} + +// Steal value from DSA, which uses recommendation from FIPS 186-3 +const numMRTests = 64 + +// Probabilistically test whether a big integer is prime. +func isPrime(i *big.Int) bool { + return i.ProbablyPrime(numMRTests) +} + +func (p *residuePoint) String() string { return p.Int.String() } + +func (p *residuePoint) Equal(p2 kyber.Point) bool { + return p.Int.Cmp(&p2.(*residuePoint).Int) == 0 +} + +func (p *residuePoint) Null() kyber.Point { + p.Int.SetInt64(1) + return p +} + +func (p *residuePoint) Base() kyber.Point { + p.Int.Set(p.g.G) + return p +} + +func (p *residuePoint) Set(p2 kyber.Point) kyber.Point { + p.g = p2.(*residuePoint).g + p.Int = p2.(*residuePoint).Int + return p +} + +func (p *residuePoint) Clone() kyber.Point { + return &residuePoint{g: p.g, Int: p.Int} +} + +func (p *residuePoint) Valid() bool { + return p.Int.Sign() > 0 && p.Int.Cmp(p.g.P) < 0 && + new(big.Int).Exp(&p.Int, p.g.Q, p.g.P).Cmp(one) == 0 +} + +func (p *residuePoint) EmbedLen() int { + // Reserve at least 8 most-significant bits for randomness, + // and the least-significant 16 bits for embedded data length. + return (p.g.P.BitLen() - 8 - 16) / 8 +} + +func (p *residuePoint) Pick(rand cipher.Stream) kyber.Point { + return p.Embed(nil, rand) +} + +// Embed the given data with some pseudo-random bits. +// This will only work efficiently for quadratic residue groups! +func (p *residuePoint) Embed(data []byte, rand cipher.Stream) kyber.Point { + + l := p.g.PointLen() + dl := p.EmbedLen() + if dl > len(data) { + dl = len(data) + } + + for { + b := random.Bits(uint(p.g.P.BitLen()), false, rand) + if data != nil { + b[l-1] = byte(dl) // Encode length in low 16 bits + b[l-2] = byte(dl >> 8) + copy(b[l-dl-2:l-2], data) // Copy in embedded data + } + p.Int.SetBytes(b) + if p.Valid() { + return p + } + } +} + +// Extract embedded data from a Residue group element +func (p *residuePoint) Data() ([]byte, error) { + b := p.Int.Bytes() + l := p.g.PointLen() + if len(b) < l { // pad leading zero bytes if necessary + b = append(make([]byte, l-len(b)), b...) + } + dl := int(b[l-2])<<8 + int(b[l-1]) + if dl > p.EmbedLen() { + return nil, errors.New("invalid embedded data length") + } + return b[l-dl-2 : l-2], nil +} + +func (p *residuePoint) Add(a, b kyber.Point) kyber.Point { + p.Int.Mul(&a.(*residuePoint).Int, &b.(*residuePoint).Int) + p.Int.Mod(&p.Int, p.g.P) + return p +} + +func (p *residuePoint) Sub(a, b kyber.Point) kyber.Point { + binv := new(big.Int).ModInverse(&b.(*residuePoint).Int, p.g.P) + p.Int.Mul(&a.(*residuePoint).Int, binv) + p.Int.Mod(&p.Int, p.g.P) + return p +} + +func (p *residuePoint) Neg(a kyber.Point) kyber.Point { + p.Int.ModInverse(&a.(*residuePoint).Int, p.g.P) + return p +} + +func (p *residuePoint) Mul(s kyber.Scalar, b kyber.Point) kyber.Point { + if b == nil { + return p.Base().Mul(s, p) + } + // to protect against golang/go#22830 + var tmp big.Int + tmp.Exp(&b.(*residuePoint).Int, &s.(*mod.Int).V, p.g.P) + p.Int = tmp + return p +} + +func (p *residuePoint) MarshalSize() int { + return (p.g.P.BitLen() + 7) / 8 +} + +func (p *residuePoint) MarshalBinary() ([]byte, error) { + b := p.Int.Bytes() // may be shorter than len(buf) + if pre := p.MarshalSize() - len(b); pre != 0 { + return append(make([]byte, pre), b...), nil + } + return b, nil +} + +func (p *residuePoint) UnmarshalBinary(data []byte) error { + p.Int.SetBytes(data) + if !p.Valid() { + return errors.New("invalid Residue group element") + } + return nil +} + +func (p *residuePoint) MarshalTo(w io.Writer) (int, error) { + return marshalling.PointMarshalTo(p, w) +} + +func (p *residuePoint) UnmarshalFrom(r io.Reader) (int, error) { + return marshalling.PointUnmarshalFrom(p, r) +} + +/* +A ResidueGroup represents a DSA-style modular integer arithmetic group, +defined by two primes P and Q and an integer R, such that P = Q*R+1. +Points in a ResidueGroup are R-residues modulo P, +and Scalars are integer exponents modulo the group order Q. + +In traditional DSA groups P is typically much larger than Q, +and hence use a large multiple R. +This is done to minimize the computational cost of modular exponentiation +while maximizing security against known classes of attacks: +P must be on the order of thousands of bits long +while for security Q is believed to require only hundreds of bits. +Such computation-optimized groups are suitable +for Diffie-Hellman agreement, DSA or ElGamal signatures, etc., +which depend on Point.Mul() and homomorphic properties. + +However, residue groups with large R are less suitable for +public-key cryptographic techniques that require choosing Points +pseudo-randomly or to contain embedded data, +as required by ElGamal encryption for example. +For such purposes quadratic residue groups are more suitable - +representing the special case where R=2 and hence P=2Q+1. +As a result, the Point.Pick() method should be expected to work efficiently +ONLY on quadratic residue groups in which R=2. +*/ +type ResidueGroup struct { + dsa.Parameters + R *big.Int +} + +func (g *ResidueGroup) String() string { + return fmt.Sprintf("Residue%d", g.P.BitLen()) +} + +// ScalarLen returns the number of bytes in the encoding of a Scalar +// for this Residue group. +func (g *ResidueGroup) ScalarLen() int { return (g.Q.BitLen() + 7) / 8 } + +// Scalar creates a Scalar associated with this Residue group, +// with an initial value of nil. +func (g *ResidueGroup) Scalar() kyber.Scalar { + return mod.NewInt64(0, g.Q) +} + +// PointLen returns the number of bytes in the encoding of a Point +// for this Residue group. +func (g *ResidueGroup) PointLen() int { return (g.P.BitLen() + 7) / 8 } + +// Point creates a Point associated with this Residue group, +// with an initial value of nil. +func (g *ResidueGroup) Point() kyber.Point { + p := new(residuePoint) + p.g = g + return p +} + +// Order returns the order of this Residue group, namely the prime Q. +func (g *ResidueGroup) Order() *big.Int { + return g.Q +} + +// Valid validates the parameters for a Residue group, +// checking that P and Q are prime, P=Q*R+1, +// and that G is a valid generator for this group. +func (g *ResidueGroup) Valid() bool { + + // Make sure both P and Q are prime + if !isPrime(g.P) || !isPrime(g.Q) { + return false + } + + // Validate the equation P = QR+1 + n := new(big.Int) + n.Mul(g.Q, g.R) + n.Add(n, one) + if n.Cmp(g.P) != 0 { + return false + } + + // Validate the generator G + if g.G.Cmp(one) <= 0 || n.Exp(g.G, g.Q, g.P).Cmp(one) != 0 { + return false + } + + return true +} + +// SetParams explicitly initializes a ResidueGroup with given parameters. +func (g *ResidueGroup) SetParams(P, Q, R, G *big.Int) { + g.P = P + g.Q = Q + g.R = R + g.G = G + if !g.Valid() { + panic("SetParams: bad Residue group parameters") + } +} + +// QuadraticResidueGroup initializes Residue group parameters for a quadratic residue group, +// by picking primes P and Q such that P=2Q+1 +// and the smallest valid generator G for this group. +func (g *ResidueGroup) QuadraticResidueGroup(bitlen uint, rand cipher.Stream) { + g.R = two + + // pick primes p,q such that p = 2q+1 + fmt.Printf("Generating %d-bit QR group", bitlen) + for i := 0; ; i++ { + if i > 1000 { + print(".") + i = 0 + } + + // First pick a prime Q + b := random.Bits(bitlen-1, true, rand) + b[len(b)-1] |= 1 // must be odd + g.Q = new(big.Int).SetBytes(b) + //println("q?",hex.EncodeToString(g.Q.Bytes())) + if !isPrime(g.Q) { + continue + } + + // Does the corresponding P come out prime too? + g.P = new(big.Int) + g.P.Mul(g.Q, two) + g.P.Add(g.P, one) + //println("p?",hex.EncodeToString(g.P.Bytes())) + if uint(g.P.BitLen()) == bitlen && isPrime(g.P) { + break + } + } + println() + println("p", g.P.String()) + println("q", g.Q.String()) + + // pick standard generator G + h := new(big.Int).Set(two) + g.G = new(big.Int) + for { + g.G.Exp(h, two, g.P) + if g.G.Cmp(one) != 0 { + break + } + h.Add(h, one) + } + println("g", g.G.String()) +} diff --git a/kyber/group/nist/suite.go b/kyber/group/nist/suite.go new file mode 100644 index 0000000000..04f6bdd835 --- /dev/null +++ b/kyber/group/nist/suite.go @@ -0,0 +1,62 @@ +package nist + +import ( + "crypto/cipher" + "crypto/sha256" + "hash" + "io" + "reflect" + + "go.dedis.ch/fixbuf" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/internal/marshalling" + "go.dedis.ch/kyber/v3/util/random" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +// Suite128 is the suite for P256 curve +type Suite128 struct { + p256 +} + +// Hash returns the instance associated with the suite +func (s *Suite128) Hash() hash.Hash { + return sha256.New() +} + +// XOF creates the XOF associated with the suite +func (s *Suite128) XOF(key []byte) kyber.XOF { + return blake2xb.New(key) +} + +// RandomStream returns a cipher.Stream that returns a key stream +// from crypto/rand. +func (s *Suite128) RandomStream() cipher.Stream { + return random.New() +} + +func (s *Suite128) Read(r io.Reader, objs ...interface{}) error { + return fixbuf.Read(r, s, objs) +} + +func (s *Suite128) Write(w io.Writer, objs ...interface{}) error { + return fixbuf.Write(w, objs) +} + +// New implements the kyber.encoding interface +func (s *Suite128) New(t reflect.Type) interface{} { + return marshalling.GroupNew(s, t) +} + +// NewBlakeSHA256P256 returns a cipher suite based on package +// go.dedis.ch/kyber/v3/xof/blake2xb, SHA-256, and the NIST P-256 +// elliptic curve. It returns random streams from Go's crypto/rand. +// +// The scalars created by this group implement kyber.Scalar's SetBytes +// method, interpreting the bytes as a big-endian integer, so as to be +// compatible with the Go standard library's big.Int type. +func NewBlakeSHA256P256() *Suite128 { + suite := new(Suite128) + suite.p256.Init() + return suite +} diff --git a/kyber/hash.go b/kyber/hash.go new file mode 100644 index 0000000000..5632df31af --- /dev/null +++ b/kyber/hash.go @@ -0,0 +1,8 @@ +package kyber + +import "hash" + +// A HashFactory is an interface that can be mixed in to local suite definitions. +type HashFactory interface { + Hash() hash.Hash +} diff --git a/kyber/pairing/adapter.go b/kyber/pairing/adapter.go new file mode 100644 index 0000000000..ade840742b --- /dev/null +++ b/kyber/pairing/adapter.go @@ -0,0 +1,51 @@ +package pairing + +import ( + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/pairing/bn256" +) + +// SuiteBn256 is an adapter that implements the suites.Suite interface so that +// bn256 can be used as a common suite to generate key pairs for instance but +// still preserves the properties of the pairing (e.g. the Pair function). +// +// It's important to note that the Point function will generate a point +// compatible with public keys only (group G2) where the signature must be +// used as a point from the group G1. +type SuiteBn256 struct { + Suite + kyber.Group +} + +// NewSuiteBn256 makes a new BN256 suite +func NewSuiteBn256() *SuiteBn256 { + return &SuiteBn256{ + Suite: bn256.NewSuite(), + } +} + +// Point generates a point from the G2 group that can only be used +// for public keys +func (s *SuiteBn256) Point() kyber.Point { + return s.G2().Point() +} + +// PointLen returns the length of a G2 point +func (s *SuiteBn256) PointLen() int { + return s.G2().PointLen() +} + +// Scalar generates a scalar +func (s *SuiteBn256) Scalar() kyber.Scalar { + return s.G1().Scalar() +} + +// ScalarLen returns the lenght of a scalar +func (s *SuiteBn256) ScalarLen() int { + return s.G1().ScalarLen() +} + +// String returns the name of the suite +func (s *SuiteBn256) String() string { + return "bn256.adapter" +} diff --git a/kyber/pairing/adapter_test.go b/kyber/pairing/adapter_test.go new file mode 100644 index 0000000000..97bbbb7283 --- /dev/null +++ b/kyber/pairing/adapter_test.go @@ -0,0 +1,28 @@ +package pairing + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3/util/key" +) + +func TestAdapter_SuiteBn256(t *testing.T) { + suite := NewSuiteBn256() + + pair := key.NewKeyPair(suite) + pubkey, err := pair.Public.MarshalBinary() + require.Nil(t, err) + privkey, err := pair.Private.MarshalBinary() + require.Nil(t, err) + + pubhex := suite.Point() + err = pubhex.UnmarshalBinary(pubkey) + require.Nil(t, err) + + privhex := suite.Scalar() + err = privhex.UnmarshalBinary(privkey) + require.Nil(t, err) + + require.Equal(t, "bn256.adapter", suite.String()) +} diff --git a/kyber/pairing/bn256/LICENSE b/kyber/pairing/bn256/LICENSE new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/kyber/pairing/bn256/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/kyber/pairing/bn256/README.md b/kyber/pairing/bn256/README.md new file mode 100644 index 0000000000..cab2ccea57 --- /dev/null +++ b/kyber/pairing/bn256/README.md @@ -0,0 +1,21 @@ +bn256 +----- + +Package bn256 implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig +curve targeting a 128-bit security level as described in the paper +[New Software Speed Records for Cryptocraphic Pairings](http://cryptojedi.org/papers/dclxvi-20100714.pdf). +Its output is compatible with the implementation described in that paper. + +The basis for this package is [Cloudflare's bn256 implementation](https://github.com/cloudflare/bn256) +which itself is an improved version of the [official bn256 package](https://golang.org/x/crypto/bn256). +The package at hand maintains compatibility to Cloudflare's library. The biggest difference is the replacement of their +[public API](https://github.com/cloudflare/bn256/blob/master/bn256.go) by a new +one that is compatible to Kyber's scalar, point, group, and suite interfaces. + +[Bilinear groups](https://en.wikipedia.org/wiki/Pairing-based_cryptography) are +the basis for many new cryptographic protocols that have been proposed over the +past decade. They consist of a triplet of groups (G₁, G₂ and GT) such that there +exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ (where gₓ is a generator of the respective +group) which is called a pairing. + + diff --git a/kyber/pairing/bn256/constants.go b/kyber/pairing/bn256/constants.go new file mode 100644 index 0000000000..943751a074 --- /dev/null +++ b/kyber/pairing/bn256/constants.go @@ -0,0 +1,56 @@ +package bn256 + +import ( + "math/big" +) + +func bigFromBase10(s string) *big.Int { + n, _ := new(big.Int).SetString(s, 10) + return n +} + +// u is the BN parameter that determines the prime: 1868033³. +var u = bigFromBase10("6518589491078791937") + +// p is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1. +var p = bigFromBase10("65000549695646603732796438742359905742825358107623003571877145026864184071783") + +// Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1. +// order-1 = (2**5) * 3 * 5743 * 280941149 * 130979359433191 * 491513138693455212421542731357 * 6518589491078791937 +var Order = bigFromBase10("65000549695646603732796438742359905742570406053903786389881062969044166799969") + +// xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+3. +var xiToPMinus1Over6 = &gfP2{gfP{0x25af52988477cdb7, 0x3d81a455ddced86a, 0x227d012e872c2431, 0x179198d3ea65d05}, gfP{0x7407634dd9cca958, 0x36d5bd6c7afb8f26, 0xf4b1c32cebd880fa, 0x6aa7869306f455f}} + +// xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = i+3. +var xiToPMinus1Over3 = &gfP2{gfP{0x4f59e37c01832e57, 0xae6be39ac2bbbfe4, 0xe04ea1bb697512f8, 0x3097caa8fc40e10e}, gfP{0xf8606916d3816f2c, 0x1e5c0d7926de927e, 0xbc45f3946d81185e, 0x80752a25aa738091}} + +// xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = i+3. +var xiToPMinus1Over2 = &gfP2{gfP{0x19da71333653ee20, 0x7eaaf34fc6ed6019, 0xc4ba3a29a60cdd1d, 0x75281311bcc9df79}, gfP{0x18dbee03fb7708fa, 0x1e7601a602c843c7, 0x5dde0688cdb231cb, 0x86db5cf2c605a524}} + +// xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = i+3. +var xiToPSquaredMinus1Over3 = &gfP{0x12d3cef5e1ada57d, 0xe2eca1463753babb, 0xca41e40ddccf750, 0x551337060397e04c} + +// xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = i+3 (a cubic root of unity, mod p). +var xiTo2PSquaredMinus2Over3 = &gfP{0x3642364f386c1db8, 0xe825f92d2acd661f, 0xf2aba7e846c19d14, 0x5a0bcea3dc52b7a0} + +// xiToPSquaredMinus1Over6 is ξ^((1p²-1)/6) where ξ = i+3 (a cubic root of -1, mod p). +var xiToPSquaredMinus1Over6 = &gfP{0xe21a761d259c78af, 0x6358fa3f5e84f7e, 0xb7c444d01ac33f0d, 0x35a9333f6e50d058} + +// xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = i+3. +var xiTo2PMinus2Over3 = &gfP2{gfP{0x51678e7469b3c52a, 0x4fb98f8b13319fc9, 0x29b2254db3f1df75, 0x1c044935a3d22fb2}, gfP{0x4d2ea218872f3d2c, 0x2fcb27fc4abe7b69, 0xd31d972f0e88ced9, 0x53adc04a00a73b15}} + +// p2 is p, represented as little-endian 64-bit words. +var p2 = [4]uint64{0x185cac6c5e089667, 0xee5b88d120b5b59e, 0xaa6fecb86184dc21, 0x8fb501e34aa387f9} + +// np is the negative inverse of p, mod 2^256. +var np = [4]uint64{0x2387f9007f17daa9, 0x734b3343ab8513c8, 0x2524282f48054c12, 0x38997ae661c3ef3c} + +// rN1 is R^-1 where R = 2^256 mod p. +var rN1 = &gfP{0xcbb781e36236117d, 0xcc65f3bcec8c91b, 0x2eab68888ea1f515, 0x1fc5c0956f92f825} + +// r2 is R^2 where R = 2^256 mod p. +var r2 = &gfP{0x9c21c3ff7e444f56, 0x409ed151b2efb0c2, 0xc6dc37b80fb1651, 0x7c36e0e62c2380b7} + +// r3 is R^3 where R = 2^256 mod p. +var r3 = &gfP{0x2af2dfb9324a5bb8, 0x388f899054f538a4, 0xdf2ff66396b107a7, 0x24ebbbb3a2529292} diff --git a/kyber/pairing/bn256/curve.go b/kyber/pairing/bn256/curve.go new file mode 100644 index 0000000000..43b1ae0f2a --- /dev/null +++ b/kyber/pairing/bn256/curve.go @@ -0,0 +1,243 @@ +package bn256 + +import ( + "fmt" + "math/big" +) + +// curvePoint implements the elliptic curve y²=x³+3. Points are kept in Jacobian +// form and t=z² when valid. G₁ is the set of points of this curve on GF(p). +type curvePoint struct { + x, y, z, t gfP +} + +var curveB = newGFp(3) + +// curveGen is the generator of G₁. +var curveGen = &curvePoint{ + x: *newGFp(1), + y: *newGFp(-2), + z: *newGFp(1), + t: *newGFp(1), +} + +func (c *curvePoint) String() string { + cpy := c.Clone() + cpy.MakeAffine() + x, y := &gfP{}, &gfP{} + montDecode(x, &cpy.x) + montDecode(y, &cpy.y) + return fmt.Sprintf("(%s, %s)", x.String(), y.String()) +} + +func (c *curvePoint) Set(a *curvePoint) { + c.x.Set(&a.x) + c.y.Set(&a.y) + c.z.Set(&a.z) + c.t.Set(&a.t) +} + +// IsOnCurve returns true iff c is on the curve. +func (c *curvePoint) IsOnCurve() bool { + c.MakeAffine() + if c.IsInfinity() { + return true + } + + y2, x3 := &gfP{}, &gfP{} + gfpMul(y2, &c.y, &c.y) + gfpMul(x3, &c.x, &c.x) + gfpMul(x3, x3, &c.x) + gfpAdd(x3, x3, curveB) + + return *y2 == *x3 +} + +func (c *curvePoint) SetInfinity() { + c.x = gfP{0} + c.y = *newGFp(1) + c.z = gfP{0} + c.t = gfP{0} +} + +func (c *curvePoint) IsInfinity() bool { + return c.z == gfP{0} +} + +func (c *curvePoint) Add(a, b *curvePoint) { + if a.IsInfinity() { + c.Set(b) + return + } + if b.IsInfinity() { + c.Set(a) + return + } + + // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 + + // Normalize the points by replacing a = [x1:y1:z1] and b = [x2:y2:z2] + // by [u1:s1:z1·z2] and [u2:s2:z1·z2] + // where u1 = x1·z2², s1 = y1·z2³ and u1 = x2·z1², s2 = y2·z1³ + z12, z22 := &gfP{}, &gfP{} + gfpMul(z12, &a.z, &a.z) + gfpMul(z22, &b.z, &b.z) + + u1, u2 := &gfP{}, &gfP{} + gfpMul(u1, &a.x, z22) + gfpMul(u2, &b.x, z12) + + t, s1 := &gfP{}, &gfP{} + gfpMul(t, &b.z, z22) + gfpMul(s1, &a.y, t) + + s2 := &gfP{} + gfpMul(t, &a.z, z12) + gfpMul(s2, &b.y, t) + + // Compute x = (2h)²(s²-u1-u2) + // where s = (s2-s1)/(u2-u1) is the slope of the line through + // (u1,s1) and (u2,s2). The extra factor 2h = 2(u2-u1) comes from the value of z below. + // This is also: + // 4(s2-s1)² - 4h²(u1+u2) = 4(s2-s1)² - 4h³ - 4h²(2u1) + // = r² - j - 2v + // with the notations below. + h := &gfP{} + gfpSub(h, u2, u1) + xEqual := *h == gfP{0} + + gfpAdd(t, h, h) + // i = 4h² + i := &gfP{} + gfpMul(i, t, t) + // j = 4h³ + j := &gfP{} + gfpMul(j, h, i) + + gfpSub(t, s2, s1) + yEqual := *t == gfP{0} + if xEqual && yEqual { + c.Double(a) + return + } + r := &gfP{} + gfpAdd(r, t, t) + + v := &gfP{} + gfpMul(v, u1, i) + + // t4 = 4(s2-s1)² + t4, t6 := &gfP{}, &gfP{} + gfpMul(t4, r, r) + gfpAdd(t, v, v) + gfpSub(t6, t4, j) + + gfpSub(&c.x, t6, t) + + // Set y = -(2h)³(s1 + s*(x/4h²-u1)) + // This is also + // y = - 2·s1·j - (s2-s1)(2x - 2i·u1) = r(v-x) - 2·s1·j + gfpSub(t, v, &c.x) // t7 + gfpMul(t4, s1, j) // t8 + gfpAdd(t6, t4, t4) // t9 + gfpMul(t4, r, t) // t10 + gfpSub(&c.y, t4, t6) + + // Set z = 2(u2-u1)·z1·z2 = 2h·z1·z2 + gfpAdd(t, &a.z, &b.z) // t11 + gfpMul(t4, t, t) // t12 + gfpSub(t, t4, z12) // t13 + gfpSub(t4, t, z22) // t14 + gfpMul(&c.z, t4, h) +} + +func (c *curvePoint) Double(a *curvePoint) { + // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 + A, B, C := &gfP{}, &gfP{}, &gfP{} + gfpMul(A, &a.x, &a.x) + gfpMul(B, &a.y, &a.y) + gfpMul(C, B, B) + + t, t2 := &gfP{}, &gfP{} + gfpAdd(t, &a.x, B) + gfpMul(t2, t, t) + gfpSub(t, t2, A) + gfpSub(t2, t, C) + + d, e, f := &gfP{}, &gfP{}, &gfP{} + gfpAdd(d, t2, t2) + gfpAdd(t, A, A) + gfpAdd(e, t, A) + gfpMul(f, e, e) + + gfpAdd(t, d, d) + gfpSub(&c.x, f, t) + + gfpAdd(t, C, C) + gfpAdd(t2, t, t) + gfpAdd(t, t2, t2) + gfpSub(&c.y, d, &c.x) + gfpMul(t2, e, &c.y) + gfpSub(&c.y, t2, t) + + gfpMul(t, &a.y, &a.z) + gfpAdd(&c.z, t, t) +} + +func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int) { + sum, t := &curvePoint{}, &curvePoint{} + sum.SetInfinity() + + for i := scalar.BitLen(); i >= 0; i-- { + t.Double(sum) + if scalar.Bit(i) != 0 { + sum.Add(t, a) + } else { + sum.Set(t) + } + } + + c.Set(sum) +} + +func (c *curvePoint) MakeAffine() { + if c.z == *newGFp(1) { + return + } else if c.z == *newGFp(0) { + c.x = gfP{0} + c.y = *newGFp(1) + c.t = gfP{0} + return + } + + zInv := &gfP{} + zInv.Invert(&c.z) + + t, zInv2 := &gfP{}, &gfP{} + gfpMul(t, &c.y, zInv) + gfpMul(zInv2, zInv, zInv) + + gfpMul(&c.x, &c.x, zInv2) + gfpMul(&c.y, t, zInv2) + + c.z = *newGFp(1) + c.t = *newGFp(1) +} + +func (c *curvePoint) Neg(a *curvePoint) { + c.x.Set(&a.x) + gfpNeg(&c.y, &a.y) + c.z.Set(&a.z) + c.t = gfP{0} +} + +// Clone makes a hard copy of the curve point +func (c *curvePoint) Clone() *curvePoint { + n := &curvePoint{} + copy(n.x[:], c.x[:]) + copy(n.y[:], c.y[:]) + copy(n.z[:], c.z[:]) + copy(n.t[:], c.t[:]) + + return n +} diff --git a/kyber/pairing/bn256/gfp.go b/kyber/pairing/bn256/gfp.go new file mode 100644 index 0000000000..aee0bbcaec --- /dev/null +++ b/kyber/pairing/bn256/gfp.go @@ -0,0 +1,69 @@ +package bn256 + +import ( + "fmt" +) + +type gfP [4]uint64 + +func newGFp(x int64) (out *gfP) { + if x >= 0 { + out = &gfP{uint64(x)} + } else { + out = &gfP{uint64(-x)} + gfpNeg(out, out) + } + + montEncode(out, out) + return out +} + +func (e *gfP) String() string { + return fmt.Sprintf("%16.16x%16.16x%16.16x%16.16x", e[3], e[2], e[1], e[0]) +} + +func (e *gfP) Set(f *gfP) { + e[0] = f[0] + e[1] = f[1] + e[2] = f[2] + e[3] = f[3] +} + +func (e *gfP) Invert(f *gfP) { + bits := [4]uint64{0x185cac6c5e089665, 0xee5b88d120b5b59e, 0xaa6fecb86184dc21, 0x8fb501e34aa387f9} + + sum, power := &gfP{}, &gfP{} + sum.Set(rN1) + power.Set(f) + + for word := 0; word < 4; word++ { + for bit := uint(0); bit < 64; bit++ { + if (bits[word]>>bit)&1 == 1 { + gfpMul(sum, sum, power) + } + gfpMul(power, power, power) + } + } + + gfpMul(sum, sum, r3) + e.Set(sum) +} + +func (e *gfP) Marshal(out []byte) { + for w := uint(0); w < 4; w++ { + for b := uint(0); b < 8; b++ { + out[8*w+b] = byte(e[3-w] >> (56 - 8*b)) + } + } +} + +func (e *gfP) Unmarshal(in []byte) { + for w := uint(0); w < 4; w++ { + for b := uint(0); b < 8; b++ { + e[3-w] += uint64(in[8*w+b]) << (56 - 8*b) + } + } +} + +func montEncode(c, a *gfP) { gfpMul(c, a, r2) } +func montDecode(c, a *gfP) { gfpMul(c, a, &gfP{1}) } diff --git a/kyber/pairing/bn256/gfp.h b/kyber/pairing/bn256/gfp.h new file mode 100644 index 0000000000..66f5a4d07d --- /dev/null +++ b/kyber/pairing/bn256/gfp.h @@ -0,0 +1,32 @@ +#define storeBlock(a0,a1,a2,a3, r) \ + MOVQ a0, 0+r \ + MOVQ a1, 8+r \ + MOVQ a2, 16+r \ + MOVQ a3, 24+r + +#define loadBlock(r, a0,a1,a2,a3) \ + MOVQ 0+r, a0 \ + MOVQ 8+r, a1 \ + MOVQ 16+r, a2 \ + MOVQ 24+r, a3 + +#define gfpCarry(a0,a1,a2,a3,a4, b0,b1,b2,b3,b4) \ + \ // b = a-p + MOVQ a0, b0 \ + MOVQ a1, b1 \ + MOVQ a2, b2 \ + MOVQ a3, b3 \ + MOVQ a4, b4 \ + \ + SUBQ ·p2+0(SB), b0 \ + SBBQ ·p2+8(SB), b1 \ + SBBQ ·p2+16(SB), b2 \ + SBBQ ·p2+24(SB), b3 \ + SBBQ $0, b4 \ + \ + \ // if b is negative then return a + \ // else return b + CMOVQCC b0, a0 \ + CMOVQCC b1, a1 \ + CMOVQCC b2, a2 \ + CMOVQCC b3, a3 diff --git a/kyber/pairing/bn256/gfp12.go b/kyber/pairing/bn256/gfp12.go new file mode 100644 index 0000000000..8835d11ec2 --- /dev/null +++ b/kyber/pairing/bn256/gfp12.go @@ -0,0 +1,231 @@ +package bn256 + +// For details of the algorithms used, see "Multiplication and Squaring on +// Pairing-Friendly Fields, Devegili et al. +// http://eprint.iacr.org/2006/471.pdf. + +import ( + "math/big" +) + +// gfP12 implements the field of size p¹² as a quadratic extension of gfP6 +// where ω²=τ. +type gfP12 struct { + x, y gfP6 // value is xω + y +} + +var gfP12Gen = &gfP12{ + x: gfP6{ + x: gfP2{ + x: gfP{0x62d608d6bb67a4fb, 0x9a66ec93f0c2032f, 0x5391628e924e1a34, 0x2162dbf7de801d0e}, + y: gfP{0x3e0c1a72bf08eb4f, 0x4972ec05990a5ecc, 0xf7b9a407ead8007e, 0x3ca04c613572ce49}, + }, + y: gfP2{ + x: gfP{0xace536a5607c910e, 0xda93774a941ddd40, 0x5de0e9853b7593ad, 0xe05bb926f513153}, + y: gfP{0x3f4c99f8abaf1a22, 0x66d5f6121f86dc33, 0x8e0a82f68a50abba, 0x819927d1eebd0695}, + }, + z: gfP2{ + x: gfP{0x7cdef49c5477faa, 0x40eb71ffedaa199d, 0xbc896661f17c9b8f, 0x3144462983c38c02}, + y: gfP{0xcd09ee8dd8418013, 0xf8d050d05faa9b11, 0x589e90a555507ee1, 0x58e4ab25f9c49c15}, + }, + }, + y: gfP6{ + x: gfP2{ + x: gfP{0x7e76809b142d020b, 0xd9949d1b2822e995, 0x3de93d974f84b076, 0x144523477028928d}, + y: gfP{0x79952799f9ef4b0, 0x4102c47aa3df01c6, 0xfa82a633c53da2e1, 0x54c3f0392f9f7e0e}, + }, + y: gfP2{ + x: gfP{0xd3432a335533272b, 0xa008fbbdc7d74f4a, 0x68e3c81eb7295ed9, 0x17fe34c21fdecef2}, + y: gfP{0xfb0bc4c0ef6df55f, 0x8bdc585b70bc2120, 0x17d498d2cb720def, 0x2a368248319b899c}, + }, + z: gfP2{ + x: gfP{0xf8487d81cb354c6c, 0x7421be69f1522caa, 0x6940c778b9fb2d54, 0x7da4b04e102bb621}, + y: gfP{0x97b91989993e7be4, 0x8526545356eab684, 0xb050073022eb1892, 0x658b432ad09939c0}, + }, + }, +} + +var gfP12Inf = &gfP12{ + x: gfP6{ + x: gfP2{ + x: gfP{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + y: gfP{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + }, + y: gfP2{ + x: gfP{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + y: gfP{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + }, + z: gfP2{ + x: gfP{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + y: gfP{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + }, + }, + y: gfP6{ + x: gfP2{ + x: gfP{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + y: gfP{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + }, + y: gfP2{ + x: gfP{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + y: gfP{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + }, + z: gfP2{ + x: gfP{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + y: gfP{0xe7a35393a1f76999, 0x11a4772edf4a4a61, 0x559013479e7b23de, 0x704afe1cb55c7806}, + }, + }, +} + +func (e *gfP12) String() string { + return "(" + e.x.String() + "," + e.y.String() + ")" +} + +func (e *gfP12) Set(a *gfP12) *gfP12 { + e.x.Set(&a.x) + e.y.Set(&a.y) + return e +} + +func (e *gfP12) SetZero() *gfP12 { + e.x.SetZero() + e.y.SetZero() + return e +} + +func (e *gfP12) SetOne() *gfP12 { + e.x.SetZero() + e.y.SetOne() + return e +} + +func (e *gfP12) IsZero() bool { + return e.x.IsZero() && e.y.IsZero() +} + +func (e *gfP12) IsOne() bool { + return e.x.IsZero() && e.y.IsOne() +} + +func (e *gfP12) Conjugate(a *gfP12) *gfP12 { + e.x.Neg(&a.x) + e.y.Set(&a.y) + return e +} + +func (e *gfP12) Neg(a *gfP12) *gfP12 { + e.x.Neg(&a.x) + e.y.Neg(&a.y) + return e +} + +// Frobenius computes (xω+y)^p = x^p ω·ξ^((p-1)/6) + y^p +func (e *gfP12) Frobenius(a *gfP12) *gfP12 { + e.x.Frobenius(&a.x) + e.y.Frobenius(&a.y) + e.x.MulScalar(&e.x, xiToPMinus1Over6) + return e +} + +// FrobeniusP2 computes (xω+y)^p² = x^p² ω·ξ^((p²-1)/6) + y^p² +func (e *gfP12) FrobeniusP2(a *gfP12) *gfP12 { + e.x.FrobeniusP2(&a.x) + e.x.MulGFP(&e.x, xiToPSquaredMinus1Over6) + e.y.FrobeniusP2(&a.y) + return e +} + +func (e *gfP12) FrobeniusP4(a *gfP12) *gfP12 { + e.x.FrobeniusP4(&a.x) + e.x.MulGFP(&e.x, xiToPSquaredMinus1Over3) + e.y.FrobeniusP4(&a.y) + return e +} + +func (e *gfP12) Add(a, b *gfP12) *gfP12 { + e.x.Add(&a.x, &b.x) + e.y.Add(&a.y, &b.y) + return e +} + +func (e *gfP12) Sub(a, b *gfP12) *gfP12 { + e.x.Sub(&a.x, &b.x) + e.y.Sub(&a.y, &b.y) + return e +} + +func (e *gfP12) Mul(a, b *gfP12) *gfP12 { + tx := (&gfP6{}).Mul(&a.x, &b.y) + t := (&gfP6{}).Mul(&b.x, &a.y) + tx.Add(tx, t) + + ty := (&gfP6{}).Mul(&a.y, &b.y) + t.Mul(&a.x, &b.x).MulTau(t) + + e.x.Set(tx) + e.y.Add(ty, t) + return e +} + +func (e *gfP12) MulScalar(a *gfP12, b *gfP6) *gfP12 { + e.x.Mul(&e.x, b) + e.y.Mul(&e.y, b) + return e +} + +func (e *gfP12) Exp(a *gfP12, power *big.Int) *gfP12 { + sum := (&gfP12{}).SetOne() + t := &gfP12{} + + for i := power.BitLen() - 1; i >= 0; i-- { + t.Square(sum) + if power.Bit(i) != 0 { + sum.Mul(t, a) + } else { + sum.Set(t) + } + } + + e.Set(sum) + return e +} + +func (e *gfP12) Square(a *gfP12) *gfP12 { + // Complex squaring algorithm + v0 := (&gfP6{}).Mul(&a.x, &a.y) + + t := (&gfP6{}).MulTau(&a.x) + t.Add(&a.y, t) + ty := (&gfP6{}).Add(&a.x, &a.y) + ty.Mul(ty, t).Sub(ty, v0) + t.MulTau(v0) + ty.Sub(ty, t) + + e.x.Add(v0, v0) + e.y.Set(ty) + return e +} + +func (e *gfP12) Invert(a *gfP12) *gfP12 { + // See "Implementing cryptographic pairings", M. Scott, section 3.2. + // ftp://136.206.11.249/pub/crypto/pairings.pdf + t1, t2 := &gfP6{}, &gfP6{} + + t1.Square(&a.x) + t2.Square(&a.y) + t1.MulTau(t1).Sub(t2, t1) + t2.Invert(t1) + + e.x.Neg(&a.x) + e.y.Set(&a.y) + e.MulScalar(e, t2) + return e +} + +// Clone makes a hard copy of the field +func (e *gfP12) Clone() *gfP12 { + n := &gfP12{} + n.x = e.x.Clone() + n.y = e.y.Clone() + + return n +} diff --git a/kyber/pairing/bn256/gfp2.go b/kyber/pairing/bn256/gfp2.go new file mode 100644 index 0000000000..5fa0ae2b4c --- /dev/null +++ b/kyber/pairing/bn256/gfp2.go @@ -0,0 +1,159 @@ +package bn256 + +// For details of the algorithms used, see "Multiplication and Squaring on +// Pairing-Friendly Fields, Devegili et al. +// http://eprint.iacr.org/2006/471.pdf. + +// gfP2 implements a field of size p² as a quadratic extension of the base field +// where i²=-1. +type gfP2 struct { + x, y gfP // value is xi+y. +} + +func gfP2Decode(in *gfP2) *gfP2 { + out := &gfP2{} + montDecode(&out.x, &in.x) + montDecode(&out.y, &in.y) + return out +} + +func (e *gfP2) String() string { + return "(" + e.x.String() + ", " + e.y.String() + ")" +} + +func (e *gfP2) Set(a *gfP2) *gfP2 { + e.x.Set(&a.x) + e.y.Set(&a.y) + return e +} + +func (e *gfP2) SetZero() *gfP2 { + e.x = gfP{0} + e.y = gfP{0} + return e +} + +func (e *gfP2) SetOne() *gfP2 { + e.x = gfP{0} + e.y = *newGFp(1) + return e +} + +func (e *gfP2) IsZero() bool { + zero := gfP{0} + return e.x == zero && e.y == zero +} + +func (e *gfP2) IsOne() bool { + zero, one := gfP{0}, *newGFp(1) + return e.x == zero && e.y == one +} + +func (e *gfP2) Conjugate(a *gfP2) *gfP2 { + e.y.Set(&a.y) + gfpNeg(&e.x, &a.x) + return e +} + +func (e *gfP2) Neg(a *gfP2) *gfP2 { + gfpNeg(&e.x, &a.x) + gfpNeg(&e.y, &a.y) + return e +} + +func (e *gfP2) Add(a, b *gfP2) *gfP2 { + gfpAdd(&e.x, &a.x, &b.x) + gfpAdd(&e.y, &a.y, &b.y) + return e +} + +func (e *gfP2) Sub(a, b *gfP2) *gfP2 { + gfpSub(&e.x, &a.x, &b.x) + gfpSub(&e.y, &a.y, &b.y) + return e +} + +// See "Multiplication and Squaring in Pairing-Friendly Fields", +// http://eprint.iacr.org/2006/471.pdf +func (e *gfP2) Mul(a, b *gfP2) *gfP2 { + tx, t := &gfP{}, &gfP{} + gfpMul(tx, &a.x, &b.y) + gfpMul(t, &b.x, &a.y) + gfpAdd(tx, tx, t) + + ty := &gfP{} + gfpMul(ty, &a.y, &b.y) + gfpMul(t, &a.x, &b.x) + gfpSub(ty, ty, t) + + e.x.Set(tx) + e.y.Set(ty) + return e +} + +func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 { + gfpMul(&e.x, &a.x, b) + gfpMul(&e.y, &a.y, b) + return e +} + +// MulXi sets e=ξa where ξ=i+3 and then returns e. +func (e *gfP2) MulXi(a *gfP2) *gfP2 { + // (xi+y)(i+3) = (3x+y)i+(3y-x) + tx := &gfP{} + gfpAdd(tx, &a.x, &a.x) + gfpAdd(tx, tx, &a.x) + gfpAdd(tx, tx, &a.y) + + ty := &gfP{} + gfpAdd(ty, &a.y, &a.y) + gfpAdd(ty, ty, &a.y) + gfpSub(ty, ty, &a.x) + + e.x.Set(tx) + e.y.Set(ty) + return e +} + +func (e *gfP2) Square(a *gfP2) *gfP2 { + // Complex squaring algorithm: + // (xi+y)² = (x+y)(y-x) + 2*i*x*y + tx, ty := &gfP{}, &gfP{} + gfpSub(tx, &a.y, &a.x) + gfpAdd(ty, &a.x, &a.y) + gfpMul(ty, tx, ty) + + gfpMul(tx, &a.x, &a.y) + gfpAdd(tx, tx, tx) + + e.x.Set(tx) + e.y.Set(ty) + return e +} + +func (e *gfP2) Invert(a *gfP2) *gfP2 { + // See "Implementing cryptographic pairings", M. Scott, section 3.2. + // ftp://136.206.11.249/pub/crypto/pairings.pdf + t1, t2 := &gfP{}, &gfP{} + gfpMul(t1, &a.x, &a.x) + gfpMul(t2, &a.y, &a.y) + gfpAdd(t1, t1, t2) + + inv := &gfP{} + inv.Invert(t1) + + gfpNeg(t1, &a.x) + + gfpMul(&e.x, t1, inv) + gfpMul(&e.y, &a.y, inv) + return e +} + +// Clone makes a hard copy of the field +func (e *gfP2) Clone() gfP2 { + n := gfP2{} + copy(n.x[:], e.x[:]) + copy(n.y[:], e.y[:]) + + return n +} diff --git a/kyber/pairing/bn256/gfp6.go b/kyber/pairing/bn256/gfp6.go new file mode 100644 index 0000000000..782e8f17f0 --- /dev/null +++ b/kyber/pairing/bn256/gfp6.go @@ -0,0 +1,224 @@ +package bn256 + +// For details of the algorithms used, see "Multiplication and Squaring on +// Pairing-Friendly Fields, Devegili et al. +// http://eprint.iacr.org/2006/471.pdf. + +// gfP6 implements the field of size p⁶ as a cubic extension of gfP2 where τ³=ξ +// and ξ=i+3. +type gfP6 struct { + x, y, z gfP2 // value is xτ² + yτ + z +} + +func (e *gfP6) String() string { + return "(" + e.x.String() + ", " + e.y.String() + ", " + e.z.String() + ")" +} + +func (e *gfP6) Set(a *gfP6) *gfP6 { + e.x.Set(&a.x) + e.y.Set(&a.y) + e.z.Set(&a.z) + return e +} + +func (e *gfP6) SetZero() *gfP6 { + e.x.SetZero() + e.y.SetZero() + e.z.SetZero() + return e +} + +func (e *gfP6) SetOne() *gfP6 { + e.x.SetZero() + e.y.SetZero() + e.z.SetOne() + return e +} + +func (e *gfP6) IsZero() bool { + return e.x.IsZero() && e.y.IsZero() && e.z.IsZero() +} + +func (e *gfP6) IsOne() bool { + return e.x.IsZero() && e.y.IsZero() && e.z.IsOne() +} + +func (e *gfP6) Neg(a *gfP6) *gfP6 { + e.x.Neg(&a.x) + e.y.Neg(&a.y) + e.z.Neg(&a.z) + return e +} + +func (e *gfP6) Frobenius(a *gfP6) *gfP6 { + e.x.Conjugate(&a.x) + e.y.Conjugate(&a.y) + e.z.Conjugate(&a.z) + + e.x.Mul(&e.x, xiTo2PMinus2Over3) + e.y.Mul(&e.y, xiToPMinus1Over3) + return e +} + +// FrobeniusP2 computes (xτ²+yτ+z)^(p²) = xτ^(2p²) + yτ^(p²) + z +func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 { + // τ^(2p²) = τ²τ^(2p²-2) = τ²ξ^((2p²-2)/3) + e.x.MulScalar(&a.x, xiTo2PSquaredMinus2Over3) + // τ^(p²) = ττ^(p²-1) = τξ^((p²-1)/3) + e.y.MulScalar(&a.y, xiToPSquaredMinus1Over3) + e.z.Set(&a.z) + return e +} + +func (e *gfP6) FrobeniusP4(a *gfP6) *gfP6 { + e.x.MulScalar(&a.x, xiToPSquaredMinus1Over3) + e.y.MulScalar(&a.y, xiTo2PSquaredMinus2Over3) + e.z.Set(&a.z) + return e +} + +func (e *gfP6) Add(a, b *gfP6) *gfP6 { + e.x.Add(&a.x, &b.x) + e.y.Add(&a.y, &b.y) + e.z.Add(&a.z, &b.z) + return e +} + +func (e *gfP6) Sub(a, b *gfP6) *gfP6 { + e.x.Sub(&a.x, &b.x) + e.y.Sub(&a.y, &b.y) + e.z.Sub(&a.z, &b.z) + return e +} + +func (e *gfP6) Mul(a, b *gfP6) *gfP6 { + // "Multiplication and Squaring on Pairing-Friendly Fields" + // Section 4, Karatsuba method. + // http://eprint.iacr.org/2006/471.pdf + v0 := (&gfP2{}).Mul(&a.z, &b.z) + v1 := (&gfP2{}).Mul(&a.y, &b.y) + v2 := (&gfP2{}).Mul(&a.x, &b.x) + + t0 := (&gfP2{}).Add(&a.x, &a.y) + t1 := (&gfP2{}).Add(&b.x, &b.y) + tz := (&gfP2{}).Mul(t0, t1) + tz.Sub(tz, v1).Sub(tz, v2).MulXi(tz).Add(tz, v0) + + t0.Add(&a.y, &a.z) + t1.Add(&b.y, &b.z) + ty := (&gfP2{}).Mul(t0, t1) + t0.MulXi(v2) + ty.Sub(ty, v0).Sub(ty, v1).Add(ty, t0) + + t0.Add(&a.x, &a.z) + t1.Add(&b.x, &b.z) + tx := (&gfP2{}).Mul(t0, t1) + tx.Sub(tx, v0).Add(tx, v1).Sub(tx, v2) + + e.x.Set(tx) + e.y.Set(ty) + e.z.Set(tz) + return e +} + +func (e *gfP6) MulScalar(a *gfP6, b *gfP2) *gfP6 { + e.x.Mul(&a.x, b) + e.y.Mul(&a.y, b) + e.z.Mul(&a.z, b) + return e +} + +func (e *gfP6) MulGFP(a *gfP6, b *gfP) *gfP6 { + e.x.MulScalar(&a.x, b) + e.y.MulScalar(&a.y, b) + e.z.MulScalar(&a.z, b) + return e +} + +// MulTau computes τ·(aτ²+bτ+c) = bτ²+cτ+aξ +func (e *gfP6) MulTau(a *gfP6) *gfP6 { + tz := (&gfP2{}).MulXi(&a.x) + ty := (&gfP2{}).Set(&a.y) + + e.y.Set(&a.z) + e.x.Set(ty) + e.z.Set(tz) + return e +} + +func (e *gfP6) Square(a *gfP6) *gfP6 { + v0 := (&gfP2{}).Square(&a.z) + v1 := (&gfP2{}).Square(&a.y) + v2 := (&gfP2{}).Square(&a.x) + + c0 := (&gfP2{}).Add(&a.x, &a.y) + c0.Square(c0).Sub(c0, v1).Sub(c0, v2).MulXi(c0).Add(c0, v0) + + c1 := (&gfP2{}).Add(&a.y, &a.z) + c1.Square(c1).Sub(c1, v0).Sub(c1, v1) + xiV2 := (&gfP2{}).MulXi(v2) + c1.Add(c1, xiV2) + + c2 := (&gfP2{}).Add(&a.x, &a.z) + c2.Square(c2).Sub(c2, v0).Add(c2, v1).Sub(c2, v2) + + e.x.Set(c2) + e.y.Set(c1) + e.z.Set(c0) + return e +} + +func (e *gfP6) Invert(a *gfP6) *gfP6 { + // See "Implementing cryptographic pairings", M. Scott, section 3.2. + // ftp://136.206.11.249/pub/crypto/pairings.pdf + + // Here we can give a short explanation of how it works: let j be a cubic root of + // unity in GF(p²) so that 1+j+j²=0. + // Then (xτ² + yτ + z)(xj²τ² + yjτ + z)(xjτ² + yj²τ + z) + // = (xτ² + yτ + z)(Cτ²+Bτ+A) + // = (x³ξ²+y³ξ+z³-3ξxyz) = F is an element of the base field (the norm). + // + // On the other hand (xj²τ² + yjτ + z)(xjτ² + yj²τ + z) + // = τ²(y²-ξxz) + τ(ξx²-yz) + (z²-ξxy) + // + // So that's why A = (z²-ξxy), B = (ξx²-yz), C = (y²-ξxz) + t1 := (&gfP2{}).Mul(&a.x, &a.y) + t1.MulXi(t1) + + A := (&gfP2{}).Square(&a.z) + A.Sub(A, t1) + + B := (&gfP2{}).Square(&a.x) + B.MulXi(B) + t1.Mul(&a.y, &a.z) + B.Sub(B, t1) + + C := (&gfP2{}).Square(&a.y) + t1.Mul(&a.x, &a.z) + C.Sub(C, t1) + + F := (&gfP2{}).Mul(C, &a.y) + F.MulXi(F) + t1.Mul(A, &a.z) + F.Add(F, t1) + t1.Mul(B, &a.x).MulXi(t1) + F.Add(F, t1) + + F.Invert(F) + + e.x.Mul(C, F) + e.y.Mul(B, F) + e.z.Mul(A, F) + return e +} + +// Clone makes a hard copy of the field +func (e *gfP6) Clone() gfP6 { + n := gfP6{ + x: e.x.Clone(), + y: e.y.Clone(), + z: e.z.Clone(), + } + + return n +} diff --git a/kyber/pairing/bn256/gfp_amd64.s b/kyber/pairing/bn256/gfp_amd64.s new file mode 100644 index 0000000000..bdb4ffb787 --- /dev/null +++ b/kyber/pairing/bn256/gfp_amd64.s @@ -0,0 +1,129 @@ +// +build amd64,!generic + +#define storeBlock(a0,a1,a2,a3, r) \ + MOVQ a0, 0+r \ + MOVQ a1, 8+r \ + MOVQ a2, 16+r \ + MOVQ a3, 24+r + +#define loadBlock(r, a0,a1,a2,a3) \ + MOVQ 0+r, a0 \ + MOVQ 8+r, a1 \ + MOVQ 16+r, a2 \ + MOVQ 24+r, a3 + +#define gfpCarry(a0,a1,a2,a3,a4, b0,b1,b2,b3,b4) \ + \ // b = a-p + MOVQ a0, b0 \ + MOVQ a1, b1 \ + MOVQ a2, b2 \ + MOVQ a3, b3 \ + MOVQ a4, b4 \ + \ + SUBQ ·p2+0(SB), b0 \ + SBBQ ·p2+8(SB), b1 \ + SBBQ ·p2+16(SB), b2 \ + SBBQ ·p2+24(SB), b3 \ + SBBQ $0, b4 \ + \ + \ // if b is negative then return a + \ // else return b + CMOVQCC b0, a0 \ + CMOVQCC b1, a1 \ + CMOVQCC b2, a2 \ + CMOVQCC b3, a3 + +#include "mul_amd64.h" +#include "mul_bmi2_amd64.h" + +TEXT ·gfpNeg(SB),0,$0-16 + MOVQ ·p2+0(SB), R8 + MOVQ ·p2+8(SB), R9 + MOVQ ·p2+16(SB), R10 + MOVQ ·p2+24(SB), R11 + + MOVQ a+8(FP), DI + SUBQ 0(DI), R8 + SBBQ 8(DI), R9 + SBBQ 16(DI), R10 + SBBQ 24(DI), R11 + + MOVQ $0, AX + gfpCarry(R8,R9,R10,R11,AX, R12,R13,R14,R15,BX) + + MOVQ c+0(FP), DI + storeBlock(R8,R9,R10,R11, 0(DI)) + RET + +TEXT ·gfpAdd(SB),0,$0-24 + MOVQ a+8(FP), DI + MOVQ b+16(FP), SI + + loadBlock(0(DI), R8,R9,R10,R11) + MOVQ $0, R12 + + ADDQ 0(SI), R8 + ADCQ 8(SI), R9 + ADCQ 16(SI), R10 + ADCQ 24(SI), R11 + ADCQ $0, R12 + + gfpCarry(R8,R9,R10,R11,R12, R13,R14,R15,AX,BX) + + MOVQ c+0(FP), DI + storeBlock(R8,R9,R10,R11, 0(DI)) + RET + +TEXT ·gfpSub(SB),0,$0-24 + MOVQ a+8(FP), DI + MOVQ b+16(FP), SI + + loadBlock(0(DI), R8,R9,R10,R11) + + MOVQ ·p2+0(SB), R12 + MOVQ ·p2+8(SB), R13 + MOVQ ·p2+16(SB), R14 + MOVQ ·p2+24(SB), R15 + MOVQ $0, AX + + SUBQ 0(SI), R8 + SBBQ 8(SI), R9 + SBBQ 16(SI), R10 + SBBQ 24(SI), R11 + + CMOVQCC AX, R12 + CMOVQCC AX, R13 + CMOVQCC AX, R14 + CMOVQCC AX, R15 + + ADDQ R12, R8 + ADCQ R13, R9 + ADCQ R14, R10 + ADCQ R15, R11 + + MOVQ c+0(FP), DI + storeBlock(R8,R9,R10,R11, 0(DI)) + RET + +TEXT ·gfpMul(SB),0,$160-24 + MOVQ a+8(FP), DI + MOVQ b+16(FP), SI + + // Jump to a slightly different implementation if MULX isn't supported. + CMPB ·hasBMI2(SB), $0 + JE nobmi2Mul + + mulBMI2(0(DI),8(DI),16(DI),24(DI), 0(SI)) + storeBlock( R8, R9,R10,R11, 0(SP)) + storeBlock(R12,R13,R14,R15, 32(SP)) + gfpReduceBMI2() + JMP end + +nobmi2Mul: + mul(0(DI),8(DI),16(DI),24(DI), 0(SI), 0(SP)) + gfpReduce(0(SP)) + +end: + MOVQ c+0(FP), DI + storeBlock(R12,R13,R14,R15, 0(DI)) + RET diff --git a/kyber/pairing/bn256/gfp_arm64.s b/kyber/pairing/bn256/gfp_arm64.s new file mode 100644 index 0000000000..c65e80168c --- /dev/null +++ b/kyber/pairing/bn256/gfp_arm64.s @@ -0,0 +1,113 @@ +// +build arm64,!generic + +#define storeBlock(a0,a1,a2,a3, r) \ + MOVD a0, 0+r \ + MOVD a1, 8+r \ + MOVD a2, 16+r \ + MOVD a3, 24+r + +#define loadBlock(r, a0,a1,a2,a3) \ + MOVD 0+r, a0 \ + MOVD 8+r, a1 \ + MOVD 16+r, a2 \ + MOVD 24+r, a3 + +#define loadModulus(p0,p1,p2,p3) \ + MOVD ·p2+0(SB), p0 \ + MOVD ·p2+8(SB), p1 \ + MOVD ·p2+16(SB), p2 \ + MOVD ·p2+24(SB), p3 + +#include "mul_arm64.h" + +TEXT ·gfpNeg(SB),0,$0-16 + MOVD a+8(FP), R0 + loadBlock(0(R0), R1,R2,R3,R4) + loadModulus(R5,R6,R7,R8) + + SUBS R1, R5, R1 + SBCS R2, R6, R2 + SBCS R3, R7, R3 + SBCS R4, R8, R4 + + SUBS R5, R1, R5 + SBCS R6, R2, R6 + SBCS R7, R3, R7 + SBCS R8, R4, R8 + + CSEL CS, R5, R1, R1 + CSEL CS, R6, R2, R2 + CSEL CS, R7, R3, R3 + CSEL CS, R8, R4, R4 + + MOVD c+0(FP), R0 + storeBlock(R1,R2,R3,R4, 0(R0)) + RET + +TEXT ·gfpAdd(SB),0,$0-24 + MOVD a+8(FP), R0 + loadBlock(0(R0), R1,R2,R3,R4) + MOVD b+16(FP), R0 + loadBlock(0(R0), R5,R6,R7,R8) + loadModulus(R9,R10,R11,R12) + MOVD ZR, R0 + + ADDS R5, R1 + ADCS R6, R2 + ADCS R7, R3 + ADCS R8, R4 + ADCS ZR, R0 + + SUBS R9, R1, R5 + SBCS R10, R2, R6 + SBCS R11, R3, R7 + SBCS R12, R4, R8 + SBCS ZR, R0, R0 + + CSEL CS, R5, R1, R1 + CSEL CS, R6, R2, R2 + CSEL CS, R7, R3, R3 + CSEL CS, R8, R4, R4 + + MOVD c+0(FP), R0 + storeBlock(R1,R2,R3,R4, 0(R0)) + RET + +TEXT ·gfpSub(SB),0,$0-24 + MOVD a+8(FP), R0 + loadBlock(0(R0), R1,R2,R3,R4) + MOVD b+16(FP), R0 + loadBlock(0(R0), R5,R6,R7,R8) + loadModulus(R9,R10,R11,R12) + + SUBS R5, R1 + SBCS R6, R2 + SBCS R7, R3 + SBCS R8, R4 + + CSEL CS, ZR, R9, R9 + CSEL CS, ZR, R10, R10 + CSEL CS, ZR, R11, R11 + CSEL CS, ZR, R12, R12 + + ADDS R9, R1 + ADCS R10, R2 + ADCS R11, R3 + ADCS R12, R4 + + MOVD c+0(FP), R0 + storeBlock(R1,R2,R3,R4, 0(R0)) + RET + +TEXT ·gfpMul(SB),0,$0-24 + MOVD a+8(FP), R0 + loadBlock(0(R0), R1,R2,R3,R4) + MOVD b+16(FP), R0 + loadBlock(0(R0), R5,R6,R7,R8) + + mul(R9,R10,R11,R12,R13,R14,R15,R16) + gfpReduce() + + MOVD c+0(FP), R0 + storeBlock(R1,R2,R3,R4, 0(R0)) + RET diff --git a/kyber/pairing/bn256/gfp_decl.go b/kyber/pairing/bn256/gfp_decl.go new file mode 100644 index 0000000000..be1b809063 --- /dev/null +++ b/kyber/pairing/bn256/gfp_decl.go @@ -0,0 +1,24 @@ +// +build amd64,!generic arm64,!generic + +package bn256 + +// This file contains forward declarations for the architecture-specific +// assembly implementations of these functions, provided that they exist. + +import ( + "golang.org/x/sys/cpu" +) + +var hasBMI2 = cpu.X86.HasBMI2 + +// go:noescape +func gfpNeg(c, a *gfP) + +//go:noescape +func gfpAdd(c, a, b *gfP) + +//go:noescape +func gfpSub(c, a, b *gfP) + +//go:noescape +func gfpMul(c, a, b *gfP) diff --git a/kyber/pairing/bn256/gfp_generic.go b/kyber/pairing/bn256/gfp_generic.go new file mode 100644 index 0000000000..8e6be95961 --- /dev/null +++ b/kyber/pairing/bn256/gfp_generic.go @@ -0,0 +1,173 @@ +// +build !amd64,!arm64 generic + +package bn256 + +func gfpCarry(a *gfP, head uint64) { + b := &gfP{} + + var carry uint64 + for i, pi := range p2 { + ai := a[i] + bi := ai - pi - carry + b[i] = bi + carry = (pi&^ai | (pi|^ai)&bi) >> 63 + } + carry = carry &^ head + + // If b is negative, then return a. + // Else return b. + carry = -carry + ncarry := ^carry + for i := 0; i < 4; i++ { + a[i] = (a[i] & carry) | (b[i] & ncarry) + } +} + +func gfpNeg(c, a *gfP) { + var carry uint64 + for i, pi := range p2 { + ai := a[i] + ci := pi - ai - carry + c[i] = ci + carry = (ai&^pi | (ai|^pi)&ci) >> 63 + } + gfpCarry(c, 0) +} + +func gfpAdd(c, a, b *gfP) { + var carry uint64 + for i, ai := range a { + bi := b[i] + ci := ai + bi + carry + c[i] = ci + carry = (ai&bi | (ai|bi)&^ci) >> 63 + } + gfpCarry(c, carry) +} + +func gfpSub(c, a, b *gfP) { + t := &gfP{} + + var carry uint64 + for i, pi := range p2 { + bi := b[i] + ti := pi - bi - carry + t[i] = ti + carry = (bi&^pi | (bi|^pi)&ti) >> 63 + } + + carry = 0 + for i, ai := range a { + ti := t[i] + ci := ai + ti + carry + c[i] = ci + carry = (ai&ti | (ai|ti)&^ci) >> 63 + } + gfpCarry(c, carry) +} + +func mul(a, b [4]uint64) [8]uint64 { + const ( + mask16 uint64 = 0x0000ffff + mask32 uint64 = 0xffffffff + ) + + var buff [32]uint64 + for i, ai := range a { + a0, a1, a2, a3 := ai&mask16, (ai>>16)&mask16, (ai>>32)&mask16, ai>>48 + + for j, bj := range b { + b0, b2 := bj&mask32, bj>>32 + + off := 4 * (i + j) + buff[off+0] += a0 * b0 + buff[off+1] += a1 * b0 + buff[off+2] += a2*b0 + a0*b2 + buff[off+3] += a3*b0 + a1*b2 + buff[off+4] += a2 * b2 + buff[off+5] += a3 * b2 + } + } + + for i := uint(1); i < 4; i++ { + shift := 16 * i + + var head, carry uint64 + for j := uint(0); j < 8; j++ { + block := 4 * j + + xi := buff[block] + yi := (buff[block+i] << shift) + head + zi := xi + yi + carry + buff[block] = zi + carry = (xi&yi | (xi|yi)&^zi) >> 63 + + head = buff[block+i] >> (64 - shift) + } + } + + return [8]uint64{buff[0], buff[4], buff[8], buff[12], buff[16], buff[20], buff[24], buff[28]} +} + +func halfMul(a, b [4]uint64) [4]uint64 { + const ( + mask16 uint64 = 0x0000ffff + mask32 uint64 = 0xffffffff + ) + + var buff [18]uint64 + for i, ai := range a { + a0, a1, a2, a3 := ai&mask16, (ai>>16)&mask16, (ai>>32)&mask16, ai>>48 + + for j, bj := range b { + if i+j > 3 { + break + } + b0, b2 := bj&mask32, bj>>32 + + off := 4 * (i + j) + buff[off+0] += a0 * b0 + buff[off+1] += a1 * b0 + buff[off+2] += a2*b0 + a0*b2 + buff[off+3] += a3*b0 + a1*b2 + buff[off+4] += a2 * b2 + buff[off+5] += a3 * b2 + } + } + + for i := uint(1); i < 4; i++ { + shift := 16 * i + + var head, carry uint64 + for j := uint(0); j < 4; j++ { + block := 4 * j + + xi := buff[block] + yi := (buff[block+i] << shift) + head + zi := xi + yi + carry + buff[block] = zi + carry = (xi&yi | (xi|yi)&^zi) >> 63 + + head = buff[block+i] >> (64 - shift) + } + } + + return [4]uint64{buff[0], buff[4], buff[8], buff[12]} +} + +func gfpMul(c, a, b *gfP) { + T := mul(*a, *b) + m := halfMul([4]uint64{T[0], T[1], T[2], T[3]}, np) + t := mul([4]uint64{m[0], m[1], m[2], m[3]}, p2) + + var carry uint64 + for i, Ti := range T { + ti := t[i] + zi := Ti + ti + carry + T[i] = zi + carry = (Ti&ti | (Ti|ti)&^zi) >> 63 + } + + *c = gfP{T[4], T[5], T[6], T[7]} + gfpCarry(c, carry) +} diff --git a/kyber/pairing/bn256/group.go b/kyber/pairing/bn256/group.go new file mode 100644 index 0000000000..9ed3039cd2 --- /dev/null +++ b/kyber/pairing/bn256/group.go @@ -0,0 +1,78 @@ +package bn256 + +import ( + "crypto/cipher" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/mod" +) + +type groupG1 struct { + common + *commonSuite +} + +func (g *groupG1) String() string { + return "bn256.G1" +} + +func (g *groupG1) PointLen() int { + return newPointG1().MarshalSize() +} + +func (g *groupG1) Point() kyber.Point { + return newPointG1() +} + +type groupG2 struct { + common + *commonSuite +} + +func (g *groupG2) String() string { + return "bn256.G2" +} + +func (g *groupG2) PointLen() int { + return newPointG2().MarshalSize() +} + +func (g *groupG2) Point() kyber.Point { + return newPointG2() +} + +type groupGT struct { + common + *commonSuite +} + +func (g *groupGT) String() string { + return "bn256.GT" +} + +func (g *groupGT) PointLen() int { + return newPointGT().MarshalSize() +} + +func (g *groupGT) Point() kyber.Point { + return newPointGT() +} + +// common functionalities across G1, G2, and GT +type common struct{} + +func (c *common) ScalarLen() int { + return mod.NewInt64(0, Order).MarshalSize() +} + +func (c *common) Scalar() kyber.Scalar { + return mod.NewInt64(0, Order) +} + +func (c *common) PrimeOrder() bool { + return true +} + +func (c *common) NewKey(rand cipher.Stream) kyber.Scalar { + return mod.NewInt64(0, Order).Pick(rand) +} diff --git a/kyber/pairing/bn256/mul_amd64.h b/kyber/pairing/bn256/mul_amd64.h new file mode 100644 index 0000000000..bab5da8313 --- /dev/null +++ b/kyber/pairing/bn256/mul_amd64.h @@ -0,0 +1,181 @@ +#define mul(a0,a1,a2,a3, rb, stack) \ + MOVQ a0, AX \ + MULQ 0+rb \ + MOVQ AX, R8 \ + MOVQ DX, R9 \ + MOVQ a0, AX \ + MULQ 8+rb \ + ADDQ AX, R9 \ + ADCQ $0, DX \ + MOVQ DX, R10 \ + MOVQ a0, AX \ + MULQ 16+rb \ + ADDQ AX, R10 \ + ADCQ $0, DX \ + MOVQ DX, R11 \ + MOVQ a0, AX \ + MULQ 24+rb \ + ADDQ AX, R11 \ + ADCQ $0, DX \ + MOVQ DX, R12 \ + \ + storeBlock(R8,R9,R10,R11, 0+stack) \ + MOVQ R12, 32+stack \ + \ + MOVQ a1, AX \ + MULQ 0+rb \ + MOVQ AX, R8 \ + MOVQ DX, R9 \ + MOVQ a1, AX \ + MULQ 8+rb \ + ADDQ AX, R9 \ + ADCQ $0, DX \ + MOVQ DX, R10 \ + MOVQ a1, AX \ + MULQ 16+rb \ + ADDQ AX, R10 \ + ADCQ $0, DX \ + MOVQ DX, R11 \ + MOVQ a1, AX \ + MULQ 24+rb \ + ADDQ AX, R11 \ + ADCQ $0, DX \ + MOVQ DX, R12 \ + \ + ADDQ 8+stack, R8 \ + ADCQ 16+stack, R9 \ + ADCQ 24+stack, R10 \ + ADCQ 32+stack, R11 \ + ADCQ $0, R12 \ + storeBlock(R8,R9,R10,R11, 8+stack) \ + MOVQ R12, 40+stack \ + \ + MOVQ a2, AX \ + MULQ 0+rb \ + MOVQ AX, R8 \ + MOVQ DX, R9 \ + MOVQ a2, AX \ + MULQ 8+rb \ + ADDQ AX, R9 \ + ADCQ $0, DX \ + MOVQ DX, R10 \ + MOVQ a2, AX \ + MULQ 16+rb \ + ADDQ AX, R10 \ + ADCQ $0, DX \ + MOVQ DX, R11 \ + MOVQ a2, AX \ + MULQ 24+rb \ + ADDQ AX, R11 \ + ADCQ $0, DX \ + MOVQ DX, R12 \ + \ + ADDQ 16+stack, R8 \ + ADCQ 24+stack, R9 \ + ADCQ 32+stack, R10 \ + ADCQ 40+stack, R11 \ + ADCQ $0, R12 \ + storeBlock(R8,R9,R10,R11, 16+stack) \ + MOVQ R12, 48+stack \ + \ + MOVQ a3, AX \ + MULQ 0+rb \ + MOVQ AX, R8 \ + MOVQ DX, R9 \ + MOVQ a3, AX \ + MULQ 8+rb \ + ADDQ AX, R9 \ + ADCQ $0, DX \ + MOVQ DX, R10 \ + MOVQ a3, AX \ + MULQ 16+rb \ + ADDQ AX, R10 \ + ADCQ $0, DX \ + MOVQ DX, R11 \ + MOVQ a3, AX \ + MULQ 24+rb \ + ADDQ AX, R11 \ + ADCQ $0, DX \ + MOVQ DX, R12 \ + \ + ADDQ 24+stack, R8 \ + ADCQ 32+stack, R9 \ + ADCQ 40+stack, R10 \ + ADCQ 48+stack, R11 \ + ADCQ $0, R12 \ + storeBlock(R8,R9,R10,R11, 24+stack) \ + MOVQ R12, 56+stack + +#define gfpReduce(stack) \ + \ // m = (T * N') mod R, store m in R8:R9:R10:R11 + MOVQ ·np+0(SB), AX \ + MULQ 0+stack \ + MOVQ AX, R8 \ + MOVQ DX, R9 \ + MOVQ ·np+0(SB), AX \ + MULQ 8+stack \ + ADDQ AX, R9 \ + ADCQ $0, DX \ + MOVQ DX, R10 \ + MOVQ ·np+0(SB), AX \ + MULQ 16+stack \ + ADDQ AX, R10 \ + ADCQ $0, DX \ + MOVQ DX, R11 \ + MOVQ ·np+0(SB), AX \ + MULQ 24+stack \ + ADDQ AX, R11 \ + \ + MOVQ ·np+8(SB), AX \ + MULQ 0+stack \ + MOVQ AX, R12 \ + MOVQ DX, R13 \ + MOVQ ·np+8(SB), AX \ + MULQ 8+stack \ + ADDQ AX, R13 \ + ADCQ $0, DX \ + MOVQ DX, R14 \ + MOVQ ·np+8(SB), AX \ + MULQ 16+stack \ + ADDQ AX, R14 \ + \ + ADDQ R12, R9 \ + ADCQ R13, R10 \ + ADCQ R14, R11 \ + \ + MOVQ ·np+16(SB), AX \ + MULQ 0+stack \ + MOVQ AX, R12 \ + MOVQ DX, R13 \ + MOVQ ·np+16(SB), AX \ + MULQ 8+stack \ + ADDQ AX, R13 \ + \ + ADDQ R12, R10 \ + ADCQ R13, R11 \ + \ + MOVQ ·np+24(SB), AX \ + MULQ 0+stack \ + ADDQ AX, R11 \ + \ + storeBlock(R8,R9,R10,R11, 64+stack) \ + \ + \ // m * N + mul(·p2+0(SB),·p2+8(SB),·p2+16(SB),·p2+24(SB), 64+stack, 96+stack) \ + \ + \ // Add the 512-bit intermediate to m*N + loadBlock(96+stack, R8,R9,R10,R11) \ + loadBlock(128+stack, R12,R13,R14,R15) \ + \ + MOVQ $0, AX \ + ADDQ 0+stack, R8 \ + ADCQ 8+stack, R9 \ + ADCQ 16+stack, R10 \ + ADCQ 24+stack, R11 \ + ADCQ 32+stack, R12 \ + ADCQ 40+stack, R13 \ + ADCQ 48+stack, R14 \ + ADCQ 56+stack, R15 \ + ADCQ $0, AX \ + \ + gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX) diff --git a/kyber/pairing/bn256/mul_arm64.h b/kyber/pairing/bn256/mul_arm64.h new file mode 100644 index 0000000000..065a9c2b89 --- /dev/null +++ b/kyber/pairing/bn256/mul_arm64.h @@ -0,0 +1,133 @@ +#define mul(c0,c1,c2,c3,c4,c5,c6,c7) \ + MUL R1, R5, c0 \ + UMULH R1, R5, c1 \ + MUL R1, R6, R0 \ + ADDS R0, c1 \ + UMULH R1, R6, c2 \ + MUL R1, R7, R0 \ + ADCS R0, c2 \ + UMULH R1, R7, c3 \ + MUL R1, R8, R0 \ + ADCS R0, c3 \ + UMULH R1, R8, c4 \ + ADCS ZR, c4 \ + \ + MUL R2, R5, R1 \ + UMULH R2, R5, R26 \ + MUL R2, R6, R0 \ + ADDS R0, R26 \ + UMULH R2, R6, R27 \ + MUL R2, R7, R0 \ + ADCS R0, R27 \ + UMULH R2, R7, R29 \ + MUL R2, R8, R0 \ + ADCS R0, R29 \ + UMULH R2, R8, c5 \ + ADCS ZR, c5 \ + ADDS R1, c1 \ + ADCS R26, c2 \ + ADCS R27, c3 \ + ADCS R29, c4 \ + ADCS ZR, c5 \ + \ + MUL R3, R5, R1 \ + UMULH R3, R5, R26 \ + MUL R3, R6, R0 \ + ADDS R0, R26 \ + UMULH R3, R6, R27 \ + MUL R3, R7, R0 \ + ADCS R0, R27 \ + UMULH R3, R7, R29 \ + MUL R3, R8, R0 \ + ADCS R0, R29 \ + UMULH R3, R8, c6 \ + ADCS ZR, c6 \ + ADDS R1, c2 \ + ADCS R26, c3 \ + ADCS R27, c4 \ + ADCS R29, c5 \ + ADCS ZR, c6 \ + \ + MUL R4, R5, R1 \ + UMULH R4, R5, R26 \ + MUL R4, R6, R0 \ + ADDS R0, R26 \ + UMULH R4, R6, R27 \ + MUL R4, R7, R0 \ + ADCS R0, R27 \ + UMULH R4, R7, R29 \ + MUL R4, R8, R0 \ + ADCS R0, R29 \ + UMULH R4, R8, c7 \ + ADCS ZR, c7 \ + ADDS R25, c3 \ + ADCS R26, c4 \ + ADCS R27, c5 \ + ADCS R29, c6 \ + ADCS ZR, c7 + +#define gfpReduce() \ + \ // m = (T * N') mod R, store m in R1:R2:R3:R4 + MOVD ·np+0(SB), R17 \ + MOVD ·np+8(SB), R25 \ + MOVD ·np+16(SB), R19 \ + MOVD ·np+24(SB), R20 \ + \ + MUL R9, R17, R1 \ + UMULH R9, R17, R2 \ + MUL R9, R25, R0 \ + ADDS R0, R2 \ + UMULH R9, R25, R3 \ + MUL R9, R19, R0 \ + ADCS R0, R3 \ + UMULH R9, R19, R4 \ + MUL R9, R20, R0 \ + ADCS R0, R4 \ + \ + MUL R10, R17, R21 \ + UMULH R10, R17, R22 \ + MUL R10, R25, R0 \ + ADDS R0, R22 \ + UMULH R10, R25, R23 \ + MUL R10, R19, R0 \ + ADCS R0, R23 \ + ADDS R21, R2 \ + ADCS R22, R3 \ + ADCS R23, R4 \ + \ + MUL R11, R17, R21 \ + UMULH R11, R17, R22 \ + MUL R11, R25, R0 \ + ADDS R0, R22 \ + ADDS R21, R3 \ + ADCS R22, R4 \ + \ + MUL R12, R17, R21 \ + ADDS R21, R4 \ + \ + \ // m * N + loadModulus(R5,R6,R7,R8) \ + mul(R17,R25,R19,R20,R21,R22,R23,R24) \ + \ + \ // Add the 512-bit intermediate to m*N + MOVD ZR, R0 \ + ADDS R9, R17 \ + ADCS R10, R25 \ + ADCS R11, R19 \ + ADCS R12, R20 \ + ADCS R13, R21 \ + ADCS R14, R22 \ + ADCS R15, R23 \ + ADCS R16, R24 \ + ADCS ZR, R0 \ + \ + \ // Our output is R21:R22:R23:R24. Reduce mod p if necessary. + SUBS R5, R21, R10 \ + SBCS R6, R22, R11 \ + SBCS R7, R23, R12 \ + SBCS R8, R24, R13 \ + \ + CSEL CS, R10, R21, R1 \ + CSEL CS, R11, R22, R2 \ + CSEL CS, R12, R23, R3 \ + CSEL CS, R13, R24, R4 diff --git a/kyber/pairing/bn256/mul_bmi2_amd64.h b/kyber/pairing/bn256/mul_bmi2_amd64.h new file mode 100644 index 0000000000..71ad0499af --- /dev/null +++ b/kyber/pairing/bn256/mul_bmi2_amd64.h @@ -0,0 +1,112 @@ +#define mulBMI2(a0,a1,a2,a3, rb) \ + MOVQ a0, DX \ + MOVQ $0, R13 \ + MULXQ 0+rb, R8, R9 \ + MULXQ 8+rb, AX, R10 \ + ADDQ AX, R9 \ + MULXQ 16+rb, AX, R11 \ + ADCQ AX, R10 \ + MULXQ 24+rb, AX, R12 \ + ADCQ AX, R11 \ + ADCQ $0, R12 \ + ADCQ $0, R13 \ + \ + MOVQ a1, DX \ + MOVQ $0, R14 \ + MULXQ 0+rb, AX, BX \ + ADDQ AX, R9 \ + ADCQ BX, R10 \ + MULXQ 16+rb, AX, BX \ + ADCQ AX, R11 \ + ADCQ BX, R12 \ + ADCQ $0, R13 \ + MULXQ 8+rb, AX, BX \ + ADDQ AX, R10 \ + ADCQ BX, R11 \ + MULXQ 24+rb, AX, BX \ + ADCQ AX, R12 \ + ADCQ BX, R13 \ + ADCQ $0, R14 \ + \ + MOVQ a2, DX \ + MOVQ $0, R15 \ + MULXQ 0+rb, AX, BX \ + ADDQ AX, R10 \ + ADCQ BX, R11 \ + MULXQ 16+rb, AX, BX \ + ADCQ AX, R12 \ + ADCQ BX, R13 \ + ADCQ $0, R14 \ + MULXQ 8+rb, AX, BX \ + ADDQ AX, R11 \ + ADCQ BX, R12 \ + MULXQ 24+rb, AX, BX \ + ADCQ AX, R13 \ + ADCQ BX, R14 \ + ADCQ $0, R15 \ + \ + MOVQ a3, DX \ + MULXQ 0+rb, AX, BX \ + ADDQ AX, R11 \ + ADCQ BX, R12 \ + MULXQ 16+rb, AX, BX \ + ADCQ AX, R13 \ + ADCQ BX, R14 \ + ADCQ $0, R15 \ + MULXQ 8+rb, AX, BX \ + ADDQ AX, R12 \ + ADCQ BX, R13 \ + MULXQ 24+rb, AX, BX \ + ADCQ AX, R14 \ + ADCQ BX, R15 + +#define gfpReduceBMI2() \ + \ // m = (T * N') mod R, store m in R8:R9:R10:R11 + MOVQ ·np+0(SB), DX \ + MULXQ 0(SP), R8, R9 \ + MULXQ 8(SP), AX, R10 \ + ADDQ AX, R9 \ + MULXQ 16(SP), AX, R11 \ + ADCQ AX, R10 \ + MULXQ 24(SP), AX, BX \ + ADCQ AX, R11 \ + \ + MOVQ ·np+8(SB), DX \ + MULXQ 0(SP), AX, BX \ + ADDQ AX, R9 \ + ADCQ BX, R10 \ + MULXQ 16(SP), AX, BX \ + ADCQ AX, R11 \ + MULXQ 8(SP), AX, BX \ + ADDQ AX, R10 \ + ADCQ BX, R11 \ + \ + MOVQ ·np+16(SB), DX \ + MULXQ 0(SP), AX, BX \ + ADDQ AX, R10 \ + ADCQ BX, R11 \ + MULXQ 8(SP), AX, BX \ + ADDQ AX, R11 \ + \ + MOVQ ·np+24(SB), DX \ + MULXQ 0(SP), AX, BX \ + ADDQ AX, R11 \ + \ + storeBlock(R8,R9,R10,R11, 64(SP)) \ + \ + \ // m * N + mulBMI2(·p2+0(SB),·p2+8(SB),·p2+16(SB),·p2+24(SB), 64(SP)) \ + \ + \ // Add the 512-bit intermediate to m*N + MOVQ $0, AX \ + ADDQ 0(SP), R8 \ + ADCQ 8(SP), R9 \ + ADCQ 16(SP), R10 \ + ADCQ 24(SP), R11 \ + ADCQ 32(SP), R12 \ + ADCQ 40(SP), R13 \ + ADCQ 48(SP), R14 \ + ADCQ 56(SP), R15 \ + ADCQ $0, AX \ + \ + gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX) diff --git a/kyber/pairing/bn256/optate.go b/kyber/pairing/bn256/optate.go new file mode 100644 index 0000000000..126c64ca6c --- /dev/null +++ b/kyber/pairing/bn256/optate.go @@ -0,0 +1,268 @@ +package bn256 + +func lineFunctionAdd(r, p *twistPoint, q *curvePoint, r2 *gfP2) (a, b, c *gfP2, rOut *twistPoint) { + // See the mixed addition algorithm from "Faster Computation of the + // Tate Pairing", http://arxiv.org/pdf/0904.0854v3.pdf + B := (&gfP2{}).Mul(&p.x, &r.t) + + D := (&gfP2{}).Add(&p.y, &r.z) + D.Square(D).Sub(D, r2).Sub(D, &r.t).Mul(D, &r.t) + + H := (&gfP2{}).Sub(B, &r.x) + I := (&gfP2{}).Square(H) + + E := (&gfP2{}).Add(I, I) + E.Add(E, E) + + J := (&gfP2{}).Mul(H, E) + + L1 := (&gfP2{}).Sub(D, &r.y) + L1.Sub(L1, &r.y) + + V := (&gfP2{}).Mul(&r.x, E) + + rOut = &twistPoint{} + rOut.x.Square(L1).Sub(&rOut.x, J).Sub(&rOut.x, V).Sub(&rOut.x, V) + + rOut.z.Add(&r.z, H).Square(&rOut.z).Sub(&rOut.z, &r.t).Sub(&rOut.z, I) + + t := (&gfP2{}).Sub(V, &rOut.x) + t.Mul(t, L1) + t2 := (&gfP2{}).Mul(&r.y, J) + t2.Add(t2, t2) + rOut.y.Sub(t, t2) + + rOut.t.Square(&rOut.z) + + t.Add(&p.y, &rOut.z).Square(t).Sub(t, r2).Sub(t, &rOut.t) + + t2.Mul(L1, &p.x) + t2.Add(t2, t2) + a = (&gfP2{}).Sub(t2, t) + + c = (&gfP2{}).MulScalar(&rOut.z, &q.y) + c.Add(c, c) + + b = (&gfP2{}).Neg(L1) + b.MulScalar(b, &q.x).Add(b, b) + + return +} + +func lineFunctionDouble(r *twistPoint, q *curvePoint) (a, b, c *gfP2, rOut *twistPoint) { + // See the doubling algorithm for a=0 from "Faster Computation of the + // Tate Pairing", http://arxiv.org/pdf/0904.0854v3.pdf + A := (&gfP2{}).Square(&r.x) + B := (&gfP2{}).Square(&r.y) + C := (&gfP2{}).Square(B) + + D := (&gfP2{}).Add(&r.x, B) + D.Square(D).Sub(D, A).Sub(D, C).Add(D, D) + + E := (&gfP2{}).Add(A, A) + E.Add(E, A) + + G := (&gfP2{}).Square(E) + + rOut = &twistPoint{} + rOut.x.Sub(G, D).Sub(&rOut.x, D) + + rOut.z.Add(&r.y, &r.z).Square(&rOut.z).Sub(&rOut.z, B).Sub(&rOut.z, &r.t) + + rOut.y.Sub(D, &rOut.x).Mul(&rOut.y, E) + t := (&gfP2{}).Add(C, C) + t.Add(t, t).Add(t, t) + rOut.y.Sub(&rOut.y, t) + + rOut.t.Square(&rOut.z) + + t.Mul(E, &r.t).Add(t, t) + b = (&gfP2{}).Neg(t) + b.MulScalar(b, &q.x) + + a = (&gfP2{}).Add(&r.x, E) + a.Square(a).Sub(a, A).Sub(a, G) + t.Add(B, B).Add(t, t) + a.Sub(a, t) + + c = (&gfP2{}).Mul(&rOut.z, &r.t) + c.Add(c, c).MulScalar(c, &q.y) + + return +} + +func mulLine(ret *gfP12, a, b, c *gfP2) { + a2 := &gfP6{} + a2.y.Set(a) + a2.z.Set(b) + a2.Mul(a2, &ret.x) + t3 := (&gfP6{}).MulScalar(&ret.y, c) + + t := (&gfP2{}).Add(b, c) + t2 := &gfP6{} + t2.y.Set(a) + t2.z.Set(t) + ret.x.Add(&ret.x, &ret.y) + + ret.y.Set(t3) + + ret.x.Mul(&ret.x, t2).Sub(&ret.x, a2).Sub(&ret.x, &ret.y) + a2.MulTau(a2) + ret.y.Add(&ret.y, a2) +} + +// sixuPlus2NAF is 6u+2 in non-adjacent form. +var sixuPlus2NAF = []int8{0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, -1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 1} + +// miller implements the Miller loop for calculating the Optimal Ate pairing. +// See algorithm 1 from http://cryptojedi.org/papers/dclxvi-20100714.pdf +func miller(q *twistPoint, p *curvePoint) *gfP12 { + ret := (&gfP12{}).SetOne() + + aAffine := &twistPoint{} + aAffine.Set(q) + aAffine.MakeAffine() + + bAffine := &curvePoint{} + bAffine.Set(p) + bAffine.MakeAffine() + + minusA := &twistPoint{} + minusA.Neg(aAffine) + + r := &twistPoint{} + r.Set(aAffine) + + r2 := (&gfP2{}).Square(&aAffine.y) + + for i := len(sixuPlus2NAF) - 1; i > 0; i-- { + a, b, c, newR := lineFunctionDouble(r, bAffine) + if i != len(sixuPlus2NAF)-1 { + ret.Square(ret) + } + + mulLine(ret, a, b, c) + r = newR + + switch sixuPlus2NAF[i-1] { + case 1: + a, b, c, newR = lineFunctionAdd(r, aAffine, bAffine, r2) + case -1: + a, b, c, newR = lineFunctionAdd(r, minusA, bAffine, r2) + default: + continue + } + + mulLine(ret, a, b, c) + r = newR + } + + // In order to calculate Q1 we have to convert q from the sextic twist + // to the full GF(p^12) group, apply the Frobenius there, and convert + // back. + // + // The twist isomorphism is (x', y') -> (xω², yω³). If we consider just + // x for a moment, then after applying the Frobenius, we have x̄ω^(2p) + // where x̄ is the conjugate of x. If we are going to apply the inverse + // isomorphism we need a value with a single coefficient of ω² so we + // rewrite this as x̄ω^(2p-2)ω². ξ⁶ = ω and, due to the construction of + // p, 2p-2 is a multiple of six. Therefore we can rewrite as + // x̄ξ^((p-1)/3)ω² and applying the inverse isomorphism eliminates the + // ω². + // + // A similar argument can be made for the y value. + + q1 := &twistPoint{} + q1.x.Conjugate(&aAffine.x).Mul(&q1.x, xiToPMinus1Over3) + q1.y.Conjugate(&aAffine.y).Mul(&q1.y, xiToPMinus1Over2) + q1.z.SetOne() + q1.t.SetOne() + + // For Q2 we are applying the p² Frobenius. The two conjugations cancel + // out and we are left only with the factors from the isomorphism. In + // the case of x, we end up with a pure number which is why + // xiToPSquaredMinus1Over3 is ∈ GF(p). With y we get a factor of -1. We + // ignore this to end up with -Q2. + + minusQ2 := &twistPoint{} + minusQ2.x.MulScalar(&aAffine.x, xiToPSquaredMinus1Over3) + minusQ2.y.Set(&aAffine.y) + minusQ2.z.SetOne() + minusQ2.t.SetOne() + + r2.Square(&q1.y) + a, b, c, newR := lineFunctionAdd(r, q1, bAffine, r2) + mulLine(ret, a, b, c) + r = newR + + r2.Square(&minusQ2.y) + a, b, c, newR = lineFunctionAdd(r, minusQ2, bAffine, r2) + mulLine(ret, a, b, c) + r = newR + + return ret +} + +// finalExponentiation computes the (p¹²-1)/Order-th power of an element of +// GF(p¹²) to obtain an element of GT (steps 13-15 of algorithm 1 from +// http://cryptojedi.org/papers/dclxvi-20100714.pdf) +func finalExponentiation(in *gfP12) *gfP12 { + t1 := &gfP12{} + + // This is the p^6-Frobenius + t1.x.Neg(&in.x) + t1.y.Set(&in.y) + + inv := &gfP12{} + inv.Invert(in) + t1.Mul(t1, inv) + + t2 := (&gfP12{}).FrobeniusP2(t1) + t1.Mul(t1, t2) + + fp := (&gfP12{}).Frobenius(t1) + fp2 := (&gfP12{}).FrobeniusP2(t1) + fp3 := (&gfP12{}).Frobenius(fp2) + + fu := (&gfP12{}).Exp(t1, u) + fu2 := (&gfP12{}).Exp(fu, u) + fu3 := (&gfP12{}).Exp(fu2, u) + + y3 := (&gfP12{}).Frobenius(fu) + fu2p := (&gfP12{}).Frobenius(fu2) + fu3p := (&gfP12{}).Frobenius(fu3) + y2 := (&gfP12{}).FrobeniusP2(fu2) + + y0 := &gfP12{} + y0.Mul(fp, fp2).Mul(y0, fp3) + + y1 := (&gfP12{}).Conjugate(t1) + y5 := (&gfP12{}).Conjugate(fu2) + y3.Conjugate(y3) + y4 := (&gfP12{}).Mul(fu, fu2p) + y4.Conjugate(y4) + + y6 := (&gfP12{}).Mul(fu3, fu3p) + y6.Conjugate(y6) + + t0 := (&gfP12{}).Square(y6) + t0.Mul(t0, y4).Mul(t0, y5) + t1.Mul(y3, y5).Mul(t1, t0) + t0.Mul(t0, y2) + t1.Square(t1).Mul(t1, t0).Square(t1) + t0.Mul(t1, y1) + t1.Mul(t1, y0) + t0.Square(t0).Mul(t0, t1) + + return t0 +} + +func optimalAte(a *twistPoint, b *curvePoint) *gfP12 { + e := miller(a, b) + ret := finalExponentiation(e) + + if a.IsInfinity() || b.IsInfinity() { + ret.SetOne() + } + return ret +} diff --git a/kyber/pairing/bn256/point.go b/kyber/pairing/bn256/point.go new file mode 100644 index 0000000000..28316b6a2e --- /dev/null +++ b/kyber/pairing/bn256/point.go @@ -0,0 +1,647 @@ +package bn256 + +import ( + "crypto/cipher" + "crypto/sha256" + "crypto/subtle" + "errors" + "io" + "math/big" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/mod" +) + +var marshalPointID1 = [8]byte{'b', 'n', '2', '5', '6', '.', 'g', '1'} +var marshalPointID2 = [8]byte{'b', 'n', '2', '5', '6', '.', 'g', '2'} +var marshalPointIDT = [8]byte{'b', 'n', '2', '5', '6', '.', 'g', 't'} + +type pointG1 struct { + g *curvePoint +} + +func newPointG1() *pointG1 { + p := &pointG1{g: &curvePoint{}} + return p +} + +func (p *pointG1) Equal(q kyber.Point) bool { + x, _ := p.MarshalBinary() + y, _ := q.MarshalBinary() + return subtle.ConstantTimeCompare(x, y) == 1 +} + +func (p *pointG1) Null() kyber.Point { + p.g.SetInfinity() + return p +} + +func (p *pointG1) Base() kyber.Point { + p.g.Set(curveGen) + return p +} + +func (p *pointG1) Pick(rand cipher.Stream) kyber.Point { + s := mod.NewInt64(0, Order).Pick(rand) + p.Base() + p.g.Mul(p.g, &s.(*mod.Int).V) + return p +} + +func (p *pointG1) Set(q kyber.Point) kyber.Point { + x := q.(*pointG1).g + p.g.Set(x) + return p +} + +// Clone makes a hard copy of the point +func (p *pointG1) Clone() kyber.Point { + q := newPointG1() + q.g = p.g.Clone() + return q +} + +func (p *pointG1) EmbedLen() int { + panic("bn256.G1: unsupported operation") +} + +func (p *pointG1) Embed(data []byte, rand cipher.Stream) kyber.Point { + // XXX: An approach to implement this is: + // - Encode data as the x-coordinate of a point on y²=x³+3 where len(data) + // is stored in the least significant byte of x and the rest is being + // filled with random values, i.e., x = rand || data || len(data). + // - Use the Tonelli-Shanks algorithm to compute the y-coordinate. + // - Convert the new point to Jacobian coordinates and set it as p. + panic("bn256.G1: unsupported operation") +} + +func (p *pointG1) Data() ([]byte, error) { + panic("bn256.G1: unsupported operation") +} + +func (p *pointG1) Add(a, b kyber.Point) kyber.Point { + x := a.(*pointG1).g + y := b.(*pointG1).g + p.g.Add(x, y) // p = a + b + return p +} + +func (p *pointG1) Sub(a, b kyber.Point) kyber.Point { + q := newPointG1() + return p.Add(a, q.Neg(b)) +} + +func (p *pointG1) Neg(q kyber.Point) kyber.Point { + x := q.(*pointG1).g + p.g.Neg(x) + return p +} + +func (p *pointG1) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { + if q == nil { + q = newPointG1().Base() + } + t := s.(*mod.Int).V + r := q.(*pointG1).g + p.g.Mul(r, &t) + return p +} + +func (p *pointG1) MarshalBinary() ([]byte, error) { + // Clone is required as we change the point + p = p.Clone().(*pointG1) + + n := p.ElementSize() + // Take a copy so that p is not written to, so calls to MarshalBinary + // are threadsafe. + pgtemp := *p.g + pgtemp.MakeAffine() + ret := make([]byte, p.MarshalSize()) + if pgtemp.IsInfinity() { + return ret, nil + } + tmp := &gfP{} + montDecode(tmp, &pgtemp.x) + tmp.Marshal(ret) + montDecode(tmp, &pgtemp.y) + tmp.Marshal(ret[n:]) + return ret, nil +} + +func (p *pointG1) MarshalID() [8]byte { + return marshalPointID1 +} + +func (p *pointG1) MarshalTo(w io.Writer) (int, error) { + buf, err := p.MarshalBinary() + if err != nil { + return 0, err + } + return w.Write(buf) +} + +func (p *pointG1) UnmarshalBinary(buf []byte) error { + n := p.ElementSize() + if len(buf) < p.MarshalSize() { + return errors.New("bn256.G1: not enough data") + } + if p.g == nil { + p.g = &curvePoint{} + } else { + p.g.x, p.g.y = gfP{0}, gfP{0} + } + + p.g.x.Unmarshal(buf) + p.g.y.Unmarshal(buf[n:]) + montEncode(&p.g.x, &p.g.x) + montEncode(&p.g.y, &p.g.y) + + zero := gfP{0} + if p.g.x == zero && p.g.y == zero { + // This is the point at infinity + p.g.y = *newGFp(1) + p.g.z = gfP{0} + p.g.t = gfP{0} + } else { + p.g.z = *newGFp(1) + p.g.t = *newGFp(1) + } + + if !p.g.IsOnCurve() { + return errors.New("bn256.G1: malformed point") + } + + return nil +} + +func (p *pointG1) UnmarshalFrom(r io.Reader) (int, error) { + buf := make([]byte, p.MarshalSize()) + n, err := io.ReadFull(r, buf) + if err != nil { + return n, err + } + return n, p.UnmarshalBinary(buf) +} + +func (p *pointG1) MarshalSize() int { + return 2 * p.ElementSize() +} + +func (p *pointG1) ElementSize() int { + return 256 / 8 +} + +func (p *pointG1) String() string { + return "bn256.G1:" + p.g.String() +} + +func (p *pointG1) Hash(m []byte) kyber.Point { + leftPad32 := func(in []byte) []byte { + if len(in) > 32 { + panic("input cannot be more than 32 bytes") + } + + out := make([]byte, 32) + copy(out[32-len(in):], in) + return out + } + + bigX, bigY := hashToPoint(m) + if p.g == nil { + p.g = new(curvePoint) + } + + x, y := new(gfP), new(gfP) + x.Unmarshal(leftPad32(bigX.Bytes())) + y.Unmarshal(leftPad32(bigY.Bytes())) + montEncode(x, x) + montEncode(y, y) + + p.g.Set(&curvePoint{*x, *y, *newGFp(1), *newGFp(1)}) + return p +} + +// hashes a byte slice into two points on a curve represented by big.Int +// ideally we want to do this using gfP, but gfP doesn't have a ModSqrt function +func hashToPoint(m []byte) (*big.Int, *big.Int) { + // we need to convert curveB into a bigInt for our computation + intCurveB := new(big.Int) + { + decodedCurveB := new(gfP) + montDecode(decodedCurveB, curveB) + bufCurveB := make([]byte, 32) + decodedCurveB.Marshal(bufCurveB) + intCurveB.SetBytes(bufCurveB) + } + + h := sha256.Sum256(m) + x := new(big.Int).SetBytes(h[:]) + x.Mod(x, p) + + for { + xxx := new(big.Int).Mul(x, x) + xxx.Mul(xxx, x) + xxx.Mod(xxx, p) + + t := new(big.Int).Add(xxx, intCurveB) + y := new(big.Int).ModSqrt(t, p) + if y != nil { + return x, y + } + + x.Add(x, big.NewInt(1)) + } +} + +type pointG2 struct { + g *twistPoint +} + +func newPointG2() *pointG2 { + p := &pointG2{g: &twistPoint{}} + return p +} + +func (p *pointG2) Equal(q kyber.Point) bool { + x, _ := p.MarshalBinary() + y, _ := q.MarshalBinary() + return subtle.ConstantTimeCompare(x, y) == 1 +} + +func (p *pointG2) Null() kyber.Point { + p.g.SetInfinity() + return p +} + +func (p *pointG2) Base() kyber.Point { + p.g.Set(twistGen) + return p +} + +func (p *pointG2) Pick(rand cipher.Stream) kyber.Point { + s := mod.NewInt64(0, Order).Pick(rand) + p.Base() + p.g.Mul(p.g, &s.(*mod.Int).V) + return p +} + +func (p *pointG2) Set(q kyber.Point) kyber.Point { + x := q.(*pointG2).g + p.g.Set(x) + return p +} + +// Clone makes a hard copy of the field +func (p *pointG2) Clone() kyber.Point { + q := newPointG2() + q.g = p.g.Clone() + return q +} + +func (p *pointG2) EmbedLen() int { + panic("bn256.G2: unsupported operation") +} + +func (p *pointG2) Embed(data []byte, rand cipher.Stream) kyber.Point { + panic("bn256.G2: unsupported operation") +} + +func (p *pointG2) Data() ([]byte, error) { + panic("bn256.G2: unsupported operation") +} + +func (p *pointG2) Add(a, b kyber.Point) kyber.Point { + x := a.(*pointG2).g + y := b.(*pointG2).g + p.g.Add(x, y) // p = a + b + return p +} + +func (p *pointG2) Sub(a, b kyber.Point) kyber.Point { + q := newPointG2() + return p.Add(a, q.Neg(b)) +} + +func (p *pointG2) Neg(q kyber.Point) kyber.Point { + x := q.(*pointG2).g + p.g.Neg(x) + return p +} + +func (p *pointG2) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { + if q == nil { + q = newPointG2().Base() + } + t := s.(*mod.Int).V + r := q.(*pointG2).g + p.g.Mul(r, &t) + return p +} + +func (p *pointG2) MarshalBinary() ([]byte, error) { + // Clone is required as we change the point during the operation + p = p.Clone().(*pointG2) + + n := p.ElementSize() + if p.g == nil { + p.g = &twistPoint{} + } + + p.g.MakeAffine() + + ret := make([]byte, p.MarshalSize()) + if p.g.IsInfinity() { + return ret, nil + } + + temp := &gfP{} + montDecode(temp, &p.g.x.x) + temp.Marshal(ret[0*n:]) + montDecode(temp, &p.g.x.y) + temp.Marshal(ret[1*n:]) + montDecode(temp, &p.g.y.x) + temp.Marshal(ret[2*n:]) + montDecode(temp, &p.g.y.y) + temp.Marshal(ret[3*n:]) + + return ret, nil +} + +func (p *pointG2) MarshalID() [8]byte { + return marshalPointID2 +} + +func (p *pointG2) MarshalTo(w io.Writer) (int, error) { + buf, err := p.MarshalBinary() + if err != nil { + return 0, err + } + return w.Write(buf) +} + +func (p *pointG2) UnmarshalBinary(buf []byte) error { + n := p.ElementSize() + if p.g == nil { + p.g = &twistPoint{} + } + + if len(buf) < p.MarshalSize() { + return errors.New("bn256.G2: not enough data") + } + + p.g.x.x.Unmarshal(buf[0*n:]) + p.g.x.y.Unmarshal(buf[1*n:]) + p.g.y.x.Unmarshal(buf[2*n:]) + p.g.y.y.Unmarshal(buf[3*n:]) + montEncode(&p.g.x.x, &p.g.x.x) + montEncode(&p.g.x.y, &p.g.x.y) + montEncode(&p.g.y.x, &p.g.y.x) + montEncode(&p.g.y.y, &p.g.y.y) + + if p.g.x.IsZero() && p.g.y.IsZero() { + // This is the point at infinity. + p.g.y.SetOne() + p.g.z.SetZero() + p.g.t.SetZero() + } else { + p.g.z.SetOne() + p.g.t.SetOne() + + if !p.g.IsOnCurve() { + return errors.New("bn256.G2: malformed point") + } + } + return nil +} + +func (p *pointG2) UnmarshalFrom(r io.Reader) (int, error) { + buf := make([]byte, p.MarshalSize()) + n, err := io.ReadFull(r, buf) + if err != nil { + return n, err + } + return n, p.UnmarshalBinary(buf) +} + +func (p *pointG2) MarshalSize() int { + return 4 * p.ElementSize() +} + +func (p *pointG2) ElementSize() int { + return 256 / 8 +} + +func (p *pointG2) String() string { + return "bn256.G2:" + p.g.String() +} + +type pointGT struct { + g *gfP12 +} + +func newPointGT() *pointGT { + p := &pointGT{g: &gfP12{}} + return p +} + +func (p *pointGT) Equal(q kyber.Point) bool { + x, _ := p.MarshalBinary() + y, _ := q.MarshalBinary() + return subtle.ConstantTimeCompare(x, y) == 1 +} + +func (p *pointGT) Null() kyber.Point { + p.g.Set(gfP12Inf) + return p +} + +func (p *pointGT) Base() kyber.Point { + p.g.Set(gfP12Gen) + return p +} + +func (p *pointGT) Pick(rand cipher.Stream) kyber.Point { + s := mod.NewInt64(0, Order).Pick(rand) + p.Base() + p.g.Exp(p.g, &s.(*mod.Int).V) + return p +} + +func (p *pointGT) Set(q kyber.Point) kyber.Point { + x := q.(*pointGT).g + p.g.Set(x) + return p +} + +// Clone makes a hard copy of the point +func (p *pointGT) Clone() kyber.Point { + q := newPointGT() + q.g = p.g.Clone() + return q +} + +func (p *pointGT) EmbedLen() int { + panic("bn256.GT: unsupported operation") +} + +func (p *pointGT) Embed(data []byte, rand cipher.Stream) kyber.Point { + panic("bn256.GT: unsupported operation") +} + +func (p *pointGT) Data() ([]byte, error) { + panic("bn256.GT: unsupported operation") +} + +func (p *pointGT) Add(a, b kyber.Point) kyber.Point { + x := a.(*pointGT).g + y := b.(*pointGT).g + p.g.Mul(x, y) + return p +} + +func (p *pointGT) Sub(a, b kyber.Point) kyber.Point { + q := newPointGT() + return p.Add(a, q.Neg(b)) +} + +func (p *pointGT) Neg(q kyber.Point) kyber.Point { + x := q.(*pointGT).g + p.g.Conjugate(x) + return p +} + +func (p *pointGT) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { + if q == nil { + q = newPointGT().Base() + } + t := s.(*mod.Int).V + r := q.(*pointGT).g + p.g.Exp(r, &t) + return p +} + +func (p *pointGT) MarshalBinary() ([]byte, error) { + n := p.ElementSize() + ret := make([]byte, p.MarshalSize()) + temp := &gfP{} + + montDecode(temp, &p.g.x.x.x) + temp.Marshal(ret[0*n:]) + montDecode(temp, &p.g.x.x.y) + temp.Marshal(ret[1*n:]) + montDecode(temp, &p.g.x.y.x) + temp.Marshal(ret[2*n:]) + montDecode(temp, &p.g.x.y.y) + temp.Marshal(ret[3*n:]) + montDecode(temp, &p.g.x.z.x) + temp.Marshal(ret[4*n:]) + montDecode(temp, &p.g.x.z.y) + temp.Marshal(ret[5*n:]) + montDecode(temp, &p.g.y.x.x) + temp.Marshal(ret[6*n:]) + montDecode(temp, &p.g.y.x.y) + temp.Marshal(ret[7*n:]) + montDecode(temp, &p.g.y.y.x) + temp.Marshal(ret[8*n:]) + montDecode(temp, &p.g.y.y.y) + temp.Marshal(ret[9*n:]) + montDecode(temp, &p.g.y.z.x) + temp.Marshal(ret[10*n:]) + montDecode(temp, &p.g.y.z.y) + temp.Marshal(ret[11*n:]) + + return ret, nil +} + +func (p *pointGT) MarshalID() [8]byte { + return marshalPointIDT +} + +func (p *pointGT) MarshalTo(w io.Writer) (int, error) { + buf, err := p.MarshalBinary() + if err != nil { + return 0, err + } + return w.Write(buf) +} + +func (p *pointGT) UnmarshalBinary(buf []byte) error { + n := p.ElementSize() + if len(buf) < p.MarshalSize() { + return errors.New("bn256.GT: not enough data") + } + + if p.g == nil { + p.g = &gfP12{} + } + + p.g.x.x.x.Unmarshal(buf[0*n:]) + p.g.x.x.y.Unmarshal(buf[1*n:]) + p.g.x.y.x.Unmarshal(buf[2*n:]) + p.g.x.y.y.Unmarshal(buf[3*n:]) + p.g.x.z.x.Unmarshal(buf[4*n:]) + p.g.x.z.y.Unmarshal(buf[5*n:]) + p.g.y.x.x.Unmarshal(buf[6*n:]) + p.g.y.x.y.Unmarshal(buf[7*n:]) + p.g.y.y.x.Unmarshal(buf[8*n:]) + p.g.y.y.y.Unmarshal(buf[9*n:]) + p.g.y.z.x.Unmarshal(buf[10*n:]) + p.g.y.z.y.Unmarshal(buf[11*n:]) + montEncode(&p.g.x.x.x, &p.g.x.x.x) + montEncode(&p.g.x.x.y, &p.g.x.x.y) + montEncode(&p.g.x.y.x, &p.g.x.y.x) + montEncode(&p.g.x.y.y, &p.g.x.y.y) + montEncode(&p.g.x.z.x, &p.g.x.z.x) + montEncode(&p.g.x.z.y, &p.g.x.z.y) + montEncode(&p.g.y.x.x, &p.g.y.x.x) + montEncode(&p.g.y.x.y, &p.g.y.x.y) + montEncode(&p.g.y.y.x, &p.g.y.y.x) + montEncode(&p.g.y.y.y, &p.g.y.y.y) + montEncode(&p.g.y.z.x, &p.g.y.z.x) + montEncode(&p.g.y.z.y, &p.g.y.z.y) + + // TODO: check if point is on curve + + return nil +} + +func (p *pointGT) UnmarshalFrom(r io.Reader) (int, error) { + buf := make([]byte, p.MarshalSize()) + n, err := io.ReadFull(r, buf) + if err != nil { + return n, err + } + return n, p.UnmarshalBinary(buf) +} + +func (p *pointGT) MarshalSize() int { + return 12 * p.ElementSize() +} + +func (p *pointGT) ElementSize() int { + return 256 / 8 +} + +func (p *pointGT) String() string { + return "bn256.GT:" + p.g.String() +} + +func (p *pointGT) Finalize() kyber.Point { + buf := finalExponentiation(p.g) + p.g.Set(buf) + return p +} + +func (p *pointGT) Miller(p1, p2 kyber.Point) kyber.Point { + a := p1.(*pointG1).g + b := p2.(*pointG2).g + p.g.Set(miller(b, a)) + return p +} + +func (p *pointGT) Pair(p1, p2 kyber.Point) kyber.Point { + a := p1.(*pointG1).g + b := p2.(*pointG2).g + p.g.Set(optimalAte(b, a)) + return p +} diff --git a/kyber/pairing/bn256/point_test.go b/kyber/pairing/bn256/point_test.go new file mode 100644 index 0000000000..93450852cc --- /dev/null +++ b/kyber/pairing/bn256/point_test.go @@ -0,0 +1,41 @@ +package bn256 + +import ( + "bytes" + "encoding/hex" + "testing" +) + +func TestPointG1_HashToPoint(t *testing.T) { + // reference test 1 + p := new(pointG1).Hash([]byte("abc")) + pBuf, err := p.MarshalBinary() + if err != nil { + t.Error(err) + } + refBuf, err := hex.DecodeString("2ac314dc445e47f096d15425fc294601c1a7d8d27561c4fe9bb452f593f77f4705230e9663123b93c06ce0cd49a893619a92019566f326829a39d6f5ce10579d") + if err != nil { + t.Error(err) + } + if !bytes.Equal(pBuf, refBuf) { + t.Error("hash does not match reference") + } + + // reference test 2 + buf2, err := hex.DecodeString("e0a05cbb37fd6c159732a8c57b981773f7480695328b674d8a9cc083377f1811") + if err != nil { + t.Error(err) + } + p2 := new(pointG1).Hash(buf2) + p2Buf, err := p2.MarshalBinary() + if err != nil { + t.Error(err) + } + refBuf2, err := hex.DecodeString("1444853e16a3f959e9ff1da9c226958f9ee4067f82451bcf88ecc5980cf2c4d50095605d82d456fbb24b21f283842746935e0c42c7f7a8f579894d9bccede5ae") + if err != nil { + t.Error(err) + } + if !bytes.Equal(p2Buf, refBuf2) { + t.Error("hash does not match reference") + } +} diff --git a/kyber/pairing/bn256/suite.go b/kyber/pairing/bn256/suite.go new file mode 100644 index 0000000000..40655c9cb1 --- /dev/null +++ b/kyber/pairing/bn256/suite.go @@ -0,0 +1,162 @@ +package bn256 + +import ( + "crypto/cipher" + "crypto/sha256" + "hash" + "io" + "reflect" + + "go.dedis.ch/fixbuf" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/util/random" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +// Suite implements the pairing.Suite interface for the BN256 bilinear pairing. +type Suite struct { + *commonSuite + g1 *groupG1 + g2 *groupG2 + gt *groupGT +} + +// NewSuite generates and returns a new BN256 pairing suite. +func NewSuite() *Suite { + s := &Suite{commonSuite: &commonSuite{}} + s.g1 = &groupG1{commonSuite: s.commonSuite} + s.g2 = &groupG2{commonSuite: s.commonSuite} + s.gt = &groupGT{commonSuite: s.commonSuite} + return s +} + +// NewSuiteG1 returns a G1 suite. +func NewSuiteG1() *Suite { + s := NewSuite() + s.commonSuite.Group = &groupG1{commonSuite: &commonSuite{}} + return s +} + +// NewSuiteG2 returns a G2 suite. +func NewSuiteG2() *Suite { + s := NewSuite() + s.commonSuite.Group = &groupG2{commonSuite: &commonSuite{}} + return s +} + +// NewSuiteGT returns a GT suite. +func NewSuiteGT() *Suite { + s := NewSuite() + s.commonSuite.Group = &groupGT{commonSuite: &commonSuite{}} + return s +} + +// NewSuiteRand generates and returns a new BN256 suite seeded by the +// given cipher stream. +func NewSuiteRand(rand cipher.Stream) *Suite { + s := &Suite{commonSuite: &commonSuite{s: rand}} + s.g1 = &groupG1{commonSuite: s.commonSuite} + s.g2 = &groupG2{commonSuite: s.commonSuite} + s.gt = &groupGT{commonSuite: s.commonSuite} + return s +} + +// G1 returns the group G1 of the BN256 pairing. +func (s *Suite) G1() kyber.Group { + return s.g1 +} + +// G2 returns the group G2 of the BN256 pairing. +func (s *Suite) G2() kyber.Group { + return s.g2 +} + +// GT returns the group GT of the BN256 pairing. +func (s *Suite) GT() kyber.Group { + return s.gt +} + +// Pair takes the points p1 and p2 in groups G1 and G2, respectively, as input +// and computes their pairing in GT. +func (s *Suite) Pair(p1 kyber.Point, p2 kyber.Point) kyber.Point { + return s.GT().Point().(*pointGT).Pair(p1, p2) +} + +// Not used other than for reflect.TypeOf() +var aScalar kyber.Scalar +var aPoint kyber.Point +var aPointG1 pointG1 +var aPointG2 pointG2 +var aPointGT pointGT + +var tScalar = reflect.TypeOf(&aScalar).Elem() +var tPoint = reflect.TypeOf(&aPoint).Elem() +var tPointG1 = reflect.TypeOf(&aPointG1).Elem() +var tPointG2 = reflect.TypeOf(&aPointG2).Elem() +var tPointGT = reflect.TypeOf(&aPointGT).Elem() + +type commonSuite struct { + s cipher.Stream + // kyber.Group is only set if we have a combined Suite + kyber.Group +} + +// New implements the kyber.Encoding interface. +func (c *commonSuite) New(t reflect.Type) interface{} { + if c.Group == nil { + panic("cannot create Point from NewGroup - please use bn256.NewGroupG1") + } + switch t { + case tScalar: + return c.Scalar() + case tPoint: + return c.Point() + case tPointG1: + g1 := groupG1{} + return g1.Point() + case tPointG2: + g2 := groupG2{} + return g2.Point() + case tPointGT: + gt := groupGT{} + return gt.Point() + } + return nil +} + +// Read is the default implementation of kyber.Encoding interface Read. +func (c *commonSuite) Read(r io.Reader, objs ...interface{}) error { + return fixbuf.Read(r, c, objs...) +} + +// Write is the default implementation of kyber.Encoding interface Write. +func (c *commonSuite) Write(w io.Writer, objs ...interface{}) error { + return fixbuf.Write(w, objs) +} + +// Hash returns a newly instantiated sha256 hash function. +func (c *commonSuite) Hash() hash.Hash { + return sha256.New() +} + +// XOF returns a newlly instantiated blake2xb XOF function. +func (c *commonSuite) XOF(seed []byte) kyber.XOF { + return blake2xb.New(seed) +} + +// RandomStream returns a cipher.Stream which corresponds to a key stream from +// crypto/rand. +func (c *commonSuite) RandomStream() cipher.Stream { + if c.s != nil { + return c.s + } + return random.New() +} + +// String returns a recognizable string that this is a combined suite. +func (c commonSuite) String() string { + if c.Group != nil { + return c.Group.String() + } + return "bn256" +} diff --git a/kyber/pairing/bn256/suite_test.go b/kyber/pairing/bn256/suite_test.go new file mode 100644 index 0000000000..e1494b621f --- /dev/null +++ b/kyber/pairing/bn256/suite_test.go @@ -0,0 +1,351 @@ +package bn256 + +import ( + "bytes" + "fmt" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/protobuf" + "testing" + + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3/group/mod" + "go.dedis.ch/kyber/v3/util/random" + "golang.org/x/crypto/bn256" +) + +func TestScalarMarshal(t *testing.T) { + suite := NewSuite() + a := suite.G1().Scalar().Pick(random.New()) + b := suite.G1().Scalar() + am, err := a.MarshalBinary() + if err != nil { + t.Fatal(err) + } + if err := b.UnmarshalBinary(am); err != nil { + t.Fatal(err) + } + if !a.Equal(b) { + t.Fatal("bn256: scalars not equal") + } +} + +func TestScalarOps(t *testing.T) { + suite := NewSuite() + a := suite.G1().Scalar().Pick(random.New()) + b := suite.G1().Scalar().Pick(random.New()) + c := suite.G1().Scalar().Pick(random.New()) + d := suite.G1().Scalar() + e := suite.G1().Scalar() + // check that (a+b)-c == (a-c)+b + d.Add(a, b) + d.Sub(d, c) + e.Sub(a, c) + e.Add(e, b) + require.True(t, d.Equal(e)) + // check that (a*b)*c^-1 == (a*c^-1)*b + d.One() + e.One() + d.Mul(a, b) + d.Div(d, c) + e.Div(a, c) + e.Mul(e, b) + require.True(t, d.Equal(e)) + // check that (a*b*c)^-1*(a*b*c) == 1 + d.One() + e.One() + d.Mul(a, b) + d.Mul(d, c) + d.Inv(d) + e.Mul(a, b) + e.Mul(e, c) + e.Mul(e, d) + require.True(t, e.Equal(suite.G1().Scalar().One())) +} + +func TestG1(t *testing.T) { + suite := NewSuite() + k := suite.G1().Scalar().Pick(random.New()) + pa := suite.G1().Point().Mul(k, nil) + ma, err := pa.MarshalBinary() + require.Nil(t, err) + + pb := new(bn256.G1).ScalarBaseMult(&k.(*mod.Int).V) + mb := pb.Marshal() + + require.Equal(t, ma, mb) +} + +func TestG1Marshal(t *testing.T) { + suite := NewSuite() + k := suite.G1().Scalar().Pick(random.New()) + pa := suite.G1().Point().Mul(k, nil) + ma, err := pa.MarshalBinary() + require.Nil(t, err) + + pb := suite.G1().Point() + err = pb.UnmarshalBinary(ma) + require.Nil(t, err) + + mb, err := pb.MarshalBinary() + require.Nil(t, err) + + require.Equal(t, ma, mb) +} + +func TestG1Ops(t *testing.T) { + suite := NewSuite() + a := suite.G1().Point().Pick(random.New()) + b := suite.G1().Point().Pick(random.New()) + c := a.Clone() + a.Neg(a) + a.Neg(a) + if !a.Equal(c) { + t.Fatal("bn256.G1: neg failed") + } + a.Add(a, b) + a.Sub(a, b) + if !a.Equal(c) { + t.Fatal("bn256.G1: add sub failed") + } + a.Add(a, suite.G1().Point().Null()) + if !a.Equal(c) { + t.Fatal("bn256.G1: add with neutral element failed") + } +} + +func TestG2(t *testing.T) { + suite := NewSuite() + k := suite.G2().Scalar().Pick(random.New()) + require.Equal(t, "mod.int ", fmt.Sprintf("%s", k.(*mod.Int).MarshalID())) + pa := suite.G2().Point().Mul(k, nil) + require.Equal(t, "bn256.g2", fmt.Sprintf("%s", pa.(*pointG2).MarshalID())) + ma, err := pa.MarshalBinary() + require.Nil(t, err) + pb := new(bn256.G2).ScalarBaseMult(&k.(*mod.Int).V) + mb := pb.Marshal() + require.Equal(t, ma, mb) +} + +func TestG2Marshal(t *testing.T) { + suite := NewSuite() + k := suite.G2().Scalar().Pick(random.New()) + pa := suite.G2().Point().Mul(k, nil) + ma, err := pa.MarshalBinary() + require.Nil(t, err) + pb := suite.G2().Point() + err = pb.UnmarshalBinary(ma) + require.Nil(t, err) + mb, err := pb.MarshalBinary() + require.Nil(t, err) + require.Equal(t, ma, mb) +} + +func TestG2MarshalZero(t *testing.T) { + suite := NewSuite() + pa := suite.G2().Point() + ma, err := pa.MarshalBinary() + require.Nil(t, err) + pb := suite.G2().Point() + err = pb.UnmarshalBinary(ma) + require.Nil(t, err) + mb, err := pb.MarshalBinary() + require.Nil(t, err) + require.Equal(t, ma, mb) +} + +func TestG2Ops(t *testing.T) { + suite := NewSuite() + a := suite.G2().Point().Pick(random.New()) + b := suite.G2().Point().Pick(random.New()) + c := a.Clone() + a.Neg(a) + a.Neg(a) + if !a.Equal(c) { + t.Fatal("bn256.G2: neg failed") + } + a.Add(a, b) + a.Sub(a, b) + if !a.Equal(c) { + t.Fatal("bn256.G2: add sub failed") + } + a.Add(a, suite.G2().Point().Null()) + if !a.Equal(c) { + t.Fatal("bn256.G2: add with neutral element failed") + } +} + +func TestGT(t *testing.T) { + suite := NewSuite() + k := suite.GT().Scalar().Pick(random.New()) + pa := suite.GT().Point().Mul(k, nil) + ma, err := pa.MarshalBinary() + require.Nil(t, err) + mx, err := suite.GT().Point().Base().MarshalBinary() + require.Nil(t, err) + pb, ok := new(bn256.GT).Unmarshal(mx) + if !ok { + t.Fatal("unmarshal not ok") + } + pb.ScalarMult(pb, &k.(*mod.Int).V) + mb := pb.Marshal() + require.Equal(t, ma, mb) +} + +func TestGTMarshal(t *testing.T) { + suite := NewSuite() + k := suite.GT().Scalar().Pick(random.New()) + pa := suite.GT().Point().Mul(k, nil) + ma, err := pa.MarshalBinary() + require.Nil(t, err) + pb := suite.GT().Point() + err = pb.UnmarshalBinary(ma) + require.Nil(t, err) + mb, err := pb.MarshalBinary() + require.Nil(t, err) + require.Equal(t, ma, mb) +} + +func TestGTOps(t *testing.T) { + suite := NewSuite() + a := suite.GT().Point().Pick(random.New()) + b := suite.GT().Point().Pick(random.New()) + c := a.Clone() + a.Neg(a) + a.Neg(a) + if !a.Equal(c) { + t.Fatal("bn256.GT: neg failed") + } + a.Add(a, b) + a.Sub(a, b) + if !a.Equal(c) { + t.Fatal("bn256.GT: add sub failed") + } + a.Add(a, suite.GT().Point().Null()) + if !a.Equal(c) { + t.Fatal("bn256.GT: add with neutral element failed") + } +} + +func TestBilinearity(t *testing.T) { + suite := NewSuite() + a := suite.G1().Scalar().Pick(random.New()) + pa := suite.G1().Point().Mul(a, nil) + b := suite.G2().Scalar().Pick(random.New()) + pb := suite.G2().Point().Mul(b, nil) + pc := suite.Pair(pa, pb) + pd := suite.Pair(suite.G1().Point().Base(), suite.G2().Point().Base()) + pd = suite.GT().Point().Mul(a, pd) + pd = suite.GT().Point().Mul(b, pd) + require.Equal(t, pc, pd) +} + +func TestTripartiteDiffieHellman(t *testing.T) { + suite := NewSuite() + a := suite.G1().Scalar().Pick(random.New()) + b := suite.G1().Scalar().Pick(random.New()) + c := suite.G1().Scalar().Pick(random.New()) + pa, pb, pc := suite.G1().Point().Mul(a, nil), suite.G1().Point().Mul(b, nil), suite.G1().Point().Mul(c, nil) + qa, qb, qc := suite.G2().Point().Mul(a, nil), suite.G2().Point().Mul(b, nil), suite.G2().Point().Mul(c, nil) + k1 := suite.Pair(pb, qc) + k1 = suite.GT().Point().Mul(a, k1) + k2 := suite.Pair(pc, qa) + k2 = suite.GT().Point().Mul(b, k2) + k3 := suite.Pair(pa, qb) + k3 = suite.GT().Point().Mul(c, k3) + require.Equal(t, k1, k2) + require.Equal(t, k2, k3) +} + +func TestCombined(t *testing.T) { + // Making sure we can do some basic arithmetic with the suites without having + // to extract the suite using .G1(), .G2(), .GT() + basicPointTest(t, NewSuiteG1()) + basicPointTest(t, NewSuiteG2()) + basicPointTest(t, NewSuiteGT()) +} + +func basicPointTest(t *testing.T, s *Suite) { + a := s.Scalar().Pick(random.New()) + pa := s.Point().Mul(a, nil) + + b := s.Scalar().Add(a, s.Scalar().One()) + pb1 := s.Point().Mul(b, nil) + pb2 := s.Point().Add(pa, s.Point().Base()) + require.True(t, pb1.Equal(pb2)) + + aBuf, err := a.MarshalBinary() + require.Nil(t, err) + aCopy := s.Scalar() + err = aCopy.UnmarshalBinary(aBuf) + require.Nil(t, err) + require.True(t, a.Equal(aCopy)) + + paBuf, err := pa.MarshalBinary() + require.Nil(t, err) + paCopy := s.Point() + err = paCopy.UnmarshalBinary(paBuf) + require.Nil(t, err) + require.True(t, pa.Equal(paCopy)) +} + +// Test that the suite.Read works correctly for suites with a defined `Point()`. +func TestSuiteRead(t *testing.T) { + s := NewSuite() + tsr(t, NewSuiteG1(), s.G1().Point().Base()) + tsr(t, NewSuiteG2(), s.G2().Point().Base()) + tsr(t, NewSuiteGT(), s.GT().Point().Base()) +} + +// Test that the suite.Read fails for undefined `Point()` +func TestSuiteReadFail(t *testing.T) { + defer func() { + require.NotNil(t, recover()) + }() + s := NewSuite() + tsr(t, s, s.G1().Point().Base()) +} + +func tsr(t *testing.T, s *Suite, pOrig kyber.Point) { + var pBuf bytes.Buffer + err := s.Write(&pBuf, pOrig) + require.Nil(t, err) + + var pCopy kyber.Point + err = s.Read(&pBuf, &pCopy) + require.Nil(t, err) + require.True(t, pCopy.Equal(pOrig)) +} + +type tsrPoint struct { + P kyber.Point +} + +func TestSuiteProtobuf(t *testing.T) { + //bn := suites.MustFind("bn256.adapter") + bn1 := NewSuiteG1() + bn2 := NewSuiteG2() + bnT := NewSuiteGT() + + protobuf.RegisterInterface(func() interface{} { return bn1.Point() }) + protobuf.RegisterInterface(func() interface{} { return bn1.Scalar() }) + protobuf.RegisterInterface(func() interface{} { return bn2.Point() }) + protobuf.RegisterInterface(func() interface{} { return bn2.Scalar() }) + protobuf.RegisterInterface(func() interface{} { return bnT.Point() }) + protobuf.RegisterInterface(func() interface{} { return bnT.Scalar() }) + + testTsr(t, NewSuiteG1()) + testTsr(t, NewSuiteG2()) + testTsr(t, NewSuiteGT()) +} + +func testTsr(t *testing.T, s *Suite) { + p := s.Point().Base() + tp := tsrPoint{P: p} + tpBuf, err := protobuf.Encode(&tp) + require.NoError(t, err) + + tpCopy := tsrPoint{} + err = protobuf.Decode(tpBuf, &tpCopy) + require.NoError(t, err) + require.True(t, tpCopy.P.Equal(tp.P)) +} diff --git a/kyber/pairing/bn256/twist.go b/kyber/pairing/bn256/twist.go new file mode 100644 index 0000000000..be6a0ab683 --- /dev/null +++ b/kyber/pairing/bn256/twist.go @@ -0,0 +1,212 @@ +package bn256 + +import ( + "math/big" +) + +// twistPoint implements the elliptic curve y²=x³+3/ξ over GF(p²). Points are +// kept in Jacobian form and t=z² when valid. The group G₂ is the set of +// n-torsion points of this curve over GF(p²) (where n = Order) +type twistPoint struct { + x, y, z, t gfP2 +} + +var twistB = &gfP2{ + gfP{0x75046774386b8d71, 0x5bd0854a46d36cf8, 0x664327a1d41c8414, 0x96c9abb932eeb2f}, + gfP{0xb94f760fb4c5ee14, 0xdae9f8f24c3b6eb4, 0x77a675d2e52f4fe4, 0x736f31b09116c66b}, +} + +// twistGen is the generator of group G₂. +var twistGen = &twistPoint{ + gfP2{ + gfP{0x402c4ab7139e1404, 0xce1c368a183d85a4, 0xd67cf9a6cb8d3983, 0x3cf246bbc2a9fbe8}, + gfP{0x88f9f11da7cdc184, 0x18293f95d69509d3, 0xb5ce0c55a735d5a1, 0x15134189bfd45a0}, + }, + gfP2{ + gfP{0xbfac7d731e9e87a2, 0xa50bb8007962e441, 0xafe910a4e8270556, 0x5075c5429d69159a}, + gfP{0xc2e07c1463ea9e56, 0xee4442052072ebd2, 0x561a519486036937, 0x5bd9394cc0d2cce}, + }, + gfP2{*newGFp(0), *newGFp(1)}, + gfP2{*newGFp(0), *newGFp(1)}, +} + +func (c *twistPoint) String() string { + cpy := c.Clone() + cpy.MakeAffine() + x, y := gfP2Decode(&cpy.x), gfP2Decode(&cpy.y) + return "(" + x.String() + ", " + y.String() + ")" +} + +func (c *twistPoint) Set(a *twistPoint) { + c.x.Set(&a.x) + c.y.Set(&a.y) + c.z.Set(&a.z) + c.t.Set(&a.t) +} + +// IsOnCurve returns true iff c is on the curve. +func (c *twistPoint) IsOnCurve() bool { + c.MakeAffine() + if c.IsInfinity() { + return true + } + + y2, x3 := &gfP2{}, &gfP2{} + y2.Square(&c.y) + x3.Square(&c.x).Mul(x3, &c.x).Add(x3, twistB) + + return *y2 == *x3 +} + +func (c *twistPoint) SetInfinity() { + c.x.SetZero() + c.y.SetOne() + c.z.SetZero() + c.t.SetZero() +} + +func (c *twistPoint) IsInfinity() bool { + return c.z.IsZero() +} + +func (c *twistPoint) Add(a, b *twistPoint) { + // For additional comments, see the same function in curve.go. + + if a.IsInfinity() { + c.Set(b) + return + } + if b.IsInfinity() { + c.Set(a) + return + } + + // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 + z12 := (&gfP2{}).Square(&a.z) + z22 := (&gfP2{}).Square(&b.z) + u1 := (&gfP2{}).Mul(&a.x, z22) + u2 := (&gfP2{}).Mul(&b.x, z12) + + t := (&gfP2{}).Mul(&b.z, z22) + s1 := (&gfP2{}).Mul(&a.y, t) + + t.Mul(&a.z, z12) + s2 := (&gfP2{}).Mul(&b.y, t) + + h := (&gfP2{}).Sub(u2, u1) + xEqual := h.IsZero() + + t.Add(h, h) + i := (&gfP2{}).Square(t) + j := (&gfP2{}).Mul(h, i) + + t.Sub(s2, s1) + yEqual := t.IsZero() + if xEqual && yEqual { + c.Double(a) + return + } + r := (&gfP2{}).Add(t, t) + + v := (&gfP2{}).Mul(u1, i) + + t4 := (&gfP2{}).Square(r) + t.Add(v, v) + t6 := (&gfP2{}).Sub(t4, j) + c.x.Sub(t6, t) + + t.Sub(v, &c.x) // t7 + t4.Mul(s1, j) // t8 + t6.Add(t4, t4) // t9 + t4.Mul(r, t) // t10 + c.y.Sub(t4, t6) + + t.Add(&a.z, &b.z) // t11 + t4.Square(t) // t12 + t.Sub(t4, z12) // t13 + t4.Sub(t, z22) // t14 + c.z.Mul(t4, h) +} + +func (c *twistPoint) Double(a *twistPoint) { + // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 + A := (&gfP2{}).Square(&a.x) + B := (&gfP2{}).Square(&a.y) + C := (&gfP2{}).Square(B) + + t := (&gfP2{}).Add(&a.x, B) + t2 := (&gfP2{}).Square(t) + t.Sub(t2, A) + t2.Sub(t, C) + d := (&gfP2{}).Add(t2, t2) + t.Add(A, A) + e := (&gfP2{}).Add(t, A) + f := (&gfP2{}).Square(e) + + t.Add(d, d) + c.x.Sub(f, t) + + t.Add(C, C) + t2.Add(t, t) + t.Add(t2, t2) + c.y.Sub(d, &c.x) + t2.Mul(e, &c.y) + c.y.Sub(t2, t) + + t.Mul(&a.y, &a.z) + c.z.Add(t, t) +} + +func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int) { + sum, t := &twistPoint{}, &twistPoint{} + + for i := scalar.BitLen(); i >= 0; i-- { + t.Double(sum) + if scalar.Bit(i) != 0 { + sum.Add(t, a) + } else { + sum.Set(t) + } + } + + c.Set(sum) +} + +func (c *twistPoint) MakeAffine() { + if c.z.IsOne() { + return + } else if c.z.IsZero() { + c.x.SetZero() + c.y.SetOne() + c.t.SetZero() + return + } + + zInv := (&gfP2{}).Invert(&c.z) + t := (&gfP2{}).Mul(&c.y, zInv) + zInv2 := (&gfP2{}).Square(zInv) + c.y.Mul(t, zInv2) + t.Mul(&c.x, zInv2) + c.x.Set(t) + c.z.SetOne() + c.t.SetOne() +} + +func (c *twistPoint) Neg(a *twistPoint) { + c.x.Set(&a.x) + c.y.Neg(&a.y) + c.z.Set(&a.z) + c.t.SetZero() +} + +// Clone makes a hard copy of the point +func (c *twistPoint) Clone() *twistPoint { + n := &twistPoint{ + x: c.x.Clone(), + y: c.y.Clone(), + z: c.z.Clone(), + t: c.t.Clone(), + } + + return n +} diff --git a/kyber/pairing/pairing.go b/kyber/pairing/pairing.go new file mode 100644 index 0000000000..d0e70707b3 --- /dev/null +++ b/kyber/pairing/pairing.go @@ -0,0 +1,17 @@ +package pairing + +import "go.dedis.ch/kyber/v3" + +// Suite interface represents a triplet of elliptic curve groups (G₁, G₂ +// and GT) such that there exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ (where gₓ is a +// generator of the respective group) which is called a pairing. +type Suite interface { + G1() kyber.Group + G2() kyber.Group + GT() kyber.Group + Pair(p1, p2 kyber.Point) kyber.Point + kyber.Encoding + kyber.HashFactory + kyber.XOFFactory + kyber.Random +} diff --git a/kyber/proof/clique.go b/kyber/proof/clique.go new file mode 100644 index 0000000000..0fbf1c061e --- /dev/null +++ b/kyber/proof/clique.go @@ -0,0 +1,45 @@ +package proof + +// A clique protocol is a kyber.on for a cryptographic protocol +// in which every participant knows about and interacts directly +// in lock-step with every other participant in the clique. +// Clique protocols are suitable for small-scale groups, +// such as "boards of trustees" chosen from larger groups. +// +// The basic clique protocol +// assumes that nodes are always "live" and never go offline, +// but we can achieve availability via threshold kyber. + +import "go.dedis.ch/kyber/v3" + +// Protocol represents the role of a participant in a clique protocol. +// A participant is represented as a higher-order function taking a StarContext, +// which invokes the StarContext's methods to send and receive messages, +// and finally returns once the protocol has concluded for all participants. +// Returns a slice of success/error indicators, one for each participant. +// +type Protocol func(ctx Context) []error + +// Context represents a kyber.context for running a clique protocol. +// A clique protocol is initiated by a leader +// but incorporates a variable number of followers, +// all of whom operate in lock-step under the leader's direction. +// At each step, each follower produces one message; +// the leader aggregates all the followers' messages for that step +// and returns the vector of collected messages to each follower. +// Followers can drop out or be absent at any step, in which case +// they are seen as contributing an empty message in that step. +type Context interface { + + // A follower calls Step to provide its message for the next step, + // and wait for the leader to collect and distribute all messages. + // Returns the list of collected messages, one per participant. + // The returned message slice is positionally consistent across steps: + // each index consistently represents the same participant every step. + // One returned message will be the same slice as the one passed in, + // representing the calling participant's own slot. + Step(msg []byte) ([][]byte, error) + + // Get a source of private cryptographic randomness. + Random() kyber.XOF +} diff --git a/kyber/proof/context.go b/kyber/proof/context.go new file mode 100644 index 0000000000..8b1ad57937 --- /dev/null +++ b/kyber/proof/context.go @@ -0,0 +1,56 @@ +package proof + +// Prover represents the prover role in an arbitrary Sigma-protocol. +// A prover is simply a higher-order function that takes a ProverContext, +// runs the protocol while making calls to the ProverContext methods as needed, +// and returns nil on success or an error once the protocol run concludes. +// The resulting proof is embodied in the interactions with the ProverContext, +// but HashProve() may be used to encode the proof into a non-interactive proof +// using a hash function via the Fiat-Shamir heuristic. +type Prover func(ctx ProverContext) error + +// Verifier represents the verifier role in an arbitrary Sigma-protocol. +// A verifier is a higher-order function that takes a VerifierContext, +// runs the protocol while making calls to VerifierContext methods as needed, +// and returns nil on success or an error once the protocol run concludes. +type Verifier func(ctx VerifierContext) error + +// ProverContext represents the kyber.environment +// required by the prover in a Sigma protocol. +// +// In a basic 3-step Sigma protocol such as a standard digital signature, +// the prover first calls Put() one or more times +// to send commitment information to the verifier, +// then calls PubRand() to obtain a public random challenge from the verifier, +// and finally makes further calls to Put() to respond to the challenge. +// +// The prover may also call PriRand() at any time +// to obtain any private randomness needed in the proof. +// The prover should obtain secret randomness only from this source, +// so that the prover may be run deterministically if desired. +// +// More sophisticated Sigma protocols requiring more than 3 steps, +// such as the Neff shuffle, may also use this interface; +// in this case the prover simply calls PubRand() multiple times. +// +type ProverContext interface { + Put(message interface{}) error // Send message to verifier + PubRand(message ...interface{}) error // Get public randomness + PriRand(message ...interface{}) error // Get private randomness +} + +// VerifierContext represents the kyber.environment +// required by the verifier in a Sigma protocol. +// +// The verifier calls Get() to obtain the prover's message data, +// interspersed with calls to PubRand() to obtain challenge data. +// Note that the challenge itself comes from the VerifierContext, +// not from the verifier itself as in the traditional Sigma-protocol model. +// By separating challenge production from proof verification logic, +// we obtain the flexibility to use a single Verifier function +// in both non-interactive proofs (e.g., via HashProve) +// and in interactive proofs (e.g., via DeniableProver). +type VerifierContext interface { + Get(message interface{}) error // Receive message from prover + PubRand(message ...interface{}) error // Get public randomness +} diff --git a/kyber/proof/deniable.go b/kyber/proof/deniable.go new file mode 100644 index 0000000000..0208a393d8 --- /dev/null +++ b/kyber/proof/deniable.go @@ -0,0 +1,297 @@ +package proof + +import ( + "bytes" + "errors" + "fmt" + + "go.dedis.ch/kyber/v3" +) + +// DeniableProver is a Protocol implementing an interactive Sigma-protocol +// to prove a particular statement to the other participants. +// Optionally the Protocol participant can also verify +// the Sigma-protocol proofs of any or all of the other participants. +// Different participants may produce different proofs of varying sizes, +// and may even consist of different numbers of steps. +func DeniableProver(suite Suite, self int, prover Prover, + verifiers []Verifier) Protocol { + + return Protocol(func(ctx Context) []error { + dp := deniableProver{} + return dp.run(suite, self, prover, verifiers, ctx) + }) +} + +type deniableProver struct { + suite Suite // Agreed-on ciphersuite for protocol + self int // Our own node number + sc Context // Clique protocol context + + // verifiers for other nodes' proofs + dv []*deniableVerifier + + // per-step state + key []byte // Secret pre-challenge we committed to + msg *bytes.Buffer // Buffer in which to build prover msg + msgs [][]byte // All messages from last proof step + + pubrand kyber.XOF + prirand kyber.XOF + + // Error/success indicators for all participants + err []error +} + +func (dp *deniableProver) run(suite Suite, self int, prv Prover, + vrf []Verifier, sc Context) []error { + dp.suite = suite + dp.self = self + dp.sc = sc + dp.prirand = sc.Random() + + nnodes := len(vrf) + if self < 0 || self >= nnodes { + return []error{errors.New("out-of-range self node")} + } + + // Initialize error slice entries to a default error indicator, + // so that forgetting to run a verifier won't look like "success" + verr := errors.New("prover or verifier not run") + dp.err = make([]error, nnodes) + for i := range dp.err { + if i != self { + dp.err[i] = verr + } + } + + // Launch goroutines to run whichever verifiers the caller requested + dp.dv = make([]*deniableVerifier, nnodes) + for i := range vrf { + if vrf[i] != nil { + dv := deniableVerifier{} + dv.start(suite, vrf[i]) + dp.dv[i] = &dv + } + } + + // Run the prover, which will also drive the verifiers. + dp.initStep() + if err := (func(ProverContext) error)(prv)(dp); err != nil { + dp.err[self] = err + } + + // Send the last prover message. + // Make sure the verifiers get to run to completion as well + for { + stragglers, err := dp.proofStep() + if err != nil { + dp.err[self] = err + break + } + if !stragglers { + break + } + if err = dp.challengeStep(); err != nil { + dp.err[self] = err + break + } + } + + return dp.err +} + +// keySize is arbitrary, make it long enough to seed the XOF +const keySize = 128 + +// Start the message buffer off in each step with a randomness commitment +func (dp *deniableProver) initStep() { + key := make([]byte, keySize) // secret random key + _, _ = dp.prirand.Read(key) + dp.key = key + + msg := make([]byte, keySize) // send commitment to it + xof := dp.suite.XOF(key) + xof.Read(msg) + dp.msg = bytes.NewBuffer(msg) + + // The Sigma-Prover will now append its proof content to dp.msg... +} + +func (dp *deniableProver) proofStep() (bool, error) { + + // Send the randomness commit and accumulated message to the leader, + // and get all participants' commits, via our star-protocol context. + msgs, err := dp.sc.Step(dp.msg.Bytes()) + if err != nil { + return false, err + } + if !bytes.Equal(msgs[dp.self], dp.msg.Bytes()) { + return false, errors.New("own messages were corrupted") + } + dp.msgs = msgs + + // Distribute this step's prover messages + // to the relevant verifiers as well, + // waking them up in the process so they can proceed. + for i := range dp.dv { + dv := dp.dv[i] + if dv != nil && i < len(msgs) { + dv.inbox <- msgs[i][keySize:] // send to verifier + } + } + + // Collect the verifiers' responses, + // collecting error indicators from verifiers that are done. + stragglers := false + for i := range dp.dv { // collect verifier responses + dv := dp.dv[i] + if dv != nil { + done := <-dv.done // get verifier response + if done { // verifier is done + dp.err[i] = dv.err + dp.dv[i] = nil + } else { // verifier needs next challenge + stragglers = true + } + } + } + return stragglers, nil +} + +func (dp *deniableProver) challengeStep() error { + + // Send our challenge randomness to the leader, and collect all. + keys, err := dp.sc.Step(dp.key) + if err != nil { + return err + } + + // XOR together all the participants' randomness contributions, + // check them against the respective commits, + // and ensure ours is included to ensure deniability + // (even if all others turn out to be maliciously generated). + mix := make([]byte, keySize) + for i := range keys { + com := dp.msgs[i][:keySize] // node i's randomness commitment + key := keys[i] // node i's committed random key + if len(com) < keySize || len(key) < keySize { + continue // ignore participants who dropped out + } + chk := make([]byte, keySize) + dp.suite.XOF(key).Read(chk) + if !bytes.Equal(com, chk) { + return errors.New("wrong key for commit") + } + for j := 0; j < keySize; j++ { // mix in this key + mix[j] ^= key[j] + } + } + if len(keys) <= dp.self || !bytes.Equal(keys[dp.self], dp.key) { + return errors.New("our own message was corrupted") + } + + // Use the mix to produce the public randomness needed by the prover + dp.pubrand = dp.suite.XOF(mix) + + // Distribute the master challenge to any verifiers waiting for it + for i := range dp.dv { + dv := dp.dv[i] + if dv != nil { + dv.inbox <- mix // so send it + } + } + + // Setup for the next proof step + dp.initStep() + return nil +} + +func (dp *deniableProver) Put(message interface{}) error { + // Add onto accumulated prover message + return dp.suite.Write(dp.msg, message) +} + +// Prover will call this after Put()ing all commits for a given step, +// to get the master challenge to be used in its challenge/responses. +func (dp *deniableProver) PubRand(data ...interface{}) error { + + if _, err := dp.proofStep(); err != nil { // finish proof step + return err + } + if err := dp.challengeStep(); err != nil { // run challenge step + return err + } + return dp.suite.Read(dp.pubrand, data...) +} + +// Get private randomness +func (dp *deniableProver) PriRand(data ...interface{}) error { + if err := dp.suite.Read(dp.prirand, data...); err != nil { + return fmt.Errorf("error reading random stream: %v", err.Error()) + } + return nil +} + +// Interactive Sigma-protocol verifier context. +// Acts as a slave to a deniableProver instance. +type deniableVerifier struct { + suite Suite + + inbox chan []byte // Channel for receiving proofs and challenges + prbuf *bytes.Buffer // Buffer with which to read proof messages + + done chan bool // Channel for sending done status indicators + err error // When done indicates verify error if non-nil + + pubrand kyber.XOF +} + +func (dv *deniableVerifier) start(suite Suite, vrf Verifier) { + dv.suite = suite + dv.inbox = make(chan []byte) + dv.done = make(chan bool) + + // Launch a concurrent goroutine to run this verifier + go func() { + // Await the prover's first message + dv.getProof() + + // Run the verifier, providing dv as its context + dv.err = (func(VerifierContext) error)(vrf)(dv) + + // Signal verifier termination + dv.done <- true + }() +} + +func (dv *deniableVerifier) getProof() { + // Get the next message from the prover + prbuf := <-dv.inbox + dv.prbuf = bytes.NewBuffer(prbuf) +} + +// Read structured data from the proof +func (dv *deniableVerifier) Get(message interface{}) error { + return dv.suite.Read(dv.prbuf, message) +} + +// Get the next public random challenge. +func (dv *deniableVerifier) PubRand(data ...interface{}) error { + + // Signal that we need the next challenge + dv.done <- false + + // Wait for it + chal := <-dv.inbox + + // Produce the appropriate publicly random stream + dv.pubrand = dv.suite.XOF(chal) + if err := dv.suite.Read(dv.pubrand, data...); err != nil { + return err + } + + // Get the next proof message + dv.getProof() + return nil +} diff --git a/kyber/proof/deniable_test.go b/kyber/proof/deniable_test.go new file mode 100644 index 0000000000..d654baef92 --- /dev/null +++ b/kyber/proof/deniable_test.go @@ -0,0 +1,123 @@ +package proof + +import ( + "bytes" + "fmt" + "testing" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/util/random" +) + +var testSuite = edwards25519.NewBlakeSHA256Ed25519() + +type node struct { + i int + done bool + + x kyber.Scalar + X kyber.Point + + proto Protocol + outbox chan []byte + inbox chan [][]byte + + log *bytes.Buffer +} + +func (n *node) Step(msg []byte) ([][]byte, error) { + + n.outbox <- msg + msgs := <-n.inbox + return msgs, nil +} + +func (n *node) Random() kyber.XOF { + return testSuite.XOF([]byte("test seed")) +} + +func runNode(n *node) { + errs := (func(Context) []error)(n.proto)(n) + + fmt.Fprintf(n.log, "node %d finished\n", n.i) + for i := range errs { + if errs[i] == nil { + fmt.Fprintf(n.log, "- %d: SUCCESS\n", i) + } else { + fmt.Fprintf(n.log, "- %d: %s\n", i, errs[i]) + } + } + + n.done = true + n.outbox <- nil +} + +func TestDeniable(t *testing.T) { + nnodes := 5 + + suite := testSuite + rand := random.New() + B := suite.Point().Base() + + // Make some keypairs + nodes := make([]*node, nnodes) + for i := 0; i < nnodes; i++ { + n := &node{} + nodes[i] = n + n.i = i + n.x = suite.Scalar().Pick(rand) + n.X = suite.Point().Mul(n.x, nil) + n.log = &bytes.Buffer{} + } + + // Make some provers and verifiers + for i := 0; i < nnodes; i++ { + n := nodes[i] + pred := Rep("X", "x", "B") + sval := map[string]kyber.Scalar{"x": n.x} + pval := map[string]kyber.Point{"B": B, "X": n.X} + prover := pred.Prover(suite, sval, pval, nil) + + vi := (i + 2) % nnodes // which node's proof to verify + vrfs := make([]Verifier, nnodes) + vpred := Rep("X", "x", "B") + vpval := map[string]kyber.Point{"B": B, "X": nodes[vi].X} + vrfs[vi] = vpred.Verifier(suite, vpval) + + n.proto = DeniableProver(suite, i, prover, vrfs) + n.outbox = make(chan []byte) + n.inbox = make(chan [][]byte) + + go runNode(n) + } + + for { + // Collect messages from all still-active nodes + msgs := make([][]byte, nnodes) + done := true + for i := range nodes { + n := nodes[i] + if n == nil { + continue + } + done = false + msgs[i] = <-n.outbox + + if n.done { + t.Log(string(n.log.Bytes())) + nodes[i] = nil + } + } + if done { + break + } + + // Distribute all messages to all still-active nodes + for i := range nodes { + if nodes[i] != nil { + nodes[i].inbox <- msgs + } + } + } +} diff --git a/kyber/proof/dleq/dleq.go b/kyber/proof/dleq/dleq.go new file mode 100644 index 0000000000..e610ccc876 --- /dev/null +++ b/kyber/proof/dleq/dleq.go @@ -0,0 +1,134 @@ +// Package dleq provides functionality to create and verify non-interactive +// zero-knowledge (NIZK) proofs for the equality (EQ) of discrete logarithms (DL). +// This means, for two values xG and xH one can check that +// log_{G}(xG) == log_{H}(xH) +// without revealing the secret value x. +package dleq + +import ( + "errors" + + "go.dedis.ch/kyber/v3" +) + +// Suite wraps the functionalities needed by the dleq package. +type Suite interface { + kyber.Group + kyber.HashFactory + kyber.XOFFactory + kyber.Random +} + +var errorDifferentLengths = errors.New("inputs of different lengths") +var errorInvalidProof = errors.New("invalid proof") + +// Proof represents a NIZK dlog-equality proof. +type Proof struct { + C kyber.Scalar // challenge + R kyber.Scalar // response + VG kyber.Point // public commitment with respect to base point G + VH kyber.Point // public commitment with respect to base point H +} + +// NewDLEQProof computes a new NIZK dlog-equality proof for the scalar x with +// respect to base points G and H. It therefore randomly selects a commitment v +// and then computes the challenge c = H(xG,xH,vG,vH) and response r = v - cx. +// Besides the proof, this function also returns the encrypted base points xG +// and xH. +func NewDLEQProof(suite Suite, G kyber.Point, H kyber.Point, x kyber.Scalar) (proof *Proof, xG kyber.Point, xH kyber.Point, err error) { + // Encrypt base points with secret + xG = suite.Point().Mul(x, G) + xH = suite.Point().Mul(x, H) + + // Commitment + v := suite.Scalar().Pick(suite.RandomStream()) + vG := suite.Point().Mul(v, G) + vH := suite.Point().Mul(v, H) + + // Challenge + h := suite.Hash() + xG.MarshalTo(h) + xH.MarshalTo(h) + vG.MarshalTo(h) + vH.MarshalTo(h) + cb := h.Sum(nil) + c := suite.Scalar().Pick(suite.XOF(cb)) + + // Response + r := suite.Scalar() + r.Mul(x, c).Sub(v, r) + + return &Proof{c, r, vG, vH}, xG, xH, nil +} + +// NewDLEQProofBatch computes lists of NIZK dlog-equality proofs and of +// encrypted base points xG and xH. Note that the challenge is computed over all +// input values. +func NewDLEQProofBatch(suite Suite, G []kyber.Point, H []kyber.Point, secrets []kyber.Scalar) (proof []*Proof, xG []kyber.Point, xH []kyber.Point, err error) { + if len(G) != len(H) || len(H) != len(secrets) { + return nil, nil, nil, errorDifferentLengths + } + + n := len(secrets) + proofs := make([]*Proof, n) + v := make([]kyber.Scalar, n) + xG = make([]kyber.Point, n) + xH = make([]kyber.Point, n) + vG := make([]kyber.Point, n) + vH := make([]kyber.Point, n) + + for i, x := range secrets { + // Encrypt base points with secrets + xG[i] = suite.Point().Mul(x, G[i]) + xH[i] = suite.Point().Mul(x, H[i]) + + // Commitments + v[i] = suite.Scalar().Pick(suite.RandomStream()) + vG[i] = suite.Point().Mul(v[i], G[i]) + vH[i] = suite.Point().Mul(v[i], H[i]) + } + + // Collective challenge + h := suite.Hash() + for _, x := range xG { + x.MarshalTo(h) + } + for _, x := range xH { + x.MarshalTo(h) + } + for _, x := range vG { + x.MarshalTo(h) + } + for _, x := range vH { + x.MarshalTo(h) + } + cb := h.Sum(nil) + + c := suite.Scalar().Pick(suite.XOF(cb)) + + // Responses + for i, x := range secrets { + r := suite.Scalar() + r.Mul(x, c).Sub(v[i], r) + proofs[i] = &Proof{c, r, vG[i], vH[i]} + } + + return proofs, xG, xH, nil +} + +// Verify examines the validity of the NIZK dlog-equality proof. +// The proof is valid if the following two conditions hold: +// vG == rG + c(xG) +// vH == rH + c(xH) +func (p *Proof) Verify(suite Suite, G kyber.Point, H kyber.Point, xG kyber.Point, xH kyber.Point) error { + rG := suite.Point().Mul(p.R, G) + rH := suite.Point().Mul(p.R, H) + cxG := suite.Point().Mul(p.C, xG) + cxH := suite.Point().Mul(p.C, xH) + a := suite.Point().Add(rG, cxG) + b := suite.Point().Add(rH, cxH) + if !(p.VG.Equal(a) && p.VH.Equal(b)) { + return errorInvalidProof + } + return nil +} diff --git a/kyber/proof/dleq/dleq_test.go b/kyber/proof/dleq/dleq_test.go new file mode 100644 index 0000000000..e6683aa37b --- /dev/null +++ b/kyber/proof/dleq/dleq_test.go @@ -0,0 +1,61 @@ +package dleq + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/util/random" +) + +var rng = random.New() + +func TestDLEQProof(t *testing.T) { + suite := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + for i := 0; i < n; i++ { + // Create some random secrets and base points + x := suite.Scalar().Pick(rng) + g := suite.Point().Pick(rng) + h := suite.Point().Pick(rng) + proof, xG, xH, err := NewDLEQProof(suite, g, h, x) + require.Equal(t, err, nil) + require.Nil(t, proof.Verify(suite, g, h, xG, xH)) + } +} + +func TestDLEQProofBatch(t *testing.T) { + suite := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + x := make([]kyber.Scalar, n) + g := make([]kyber.Point, n) + h := make([]kyber.Point, n) + for i := range x { + x[i] = suite.Scalar().Pick(rng) + g[i] = suite.Point().Pick(rng) + h[i] = suite.Point().Pick(rng) + } + proofs, xG, xH, err := NewDLEQProofBatch(suite, g, h, x) + require.Equal(t, err, nil) + for i := range proofs { + require.Nil(t, proofs[i].Verify(suite, g[i], h[i], xG[i], xH[i])) + } +} + +func TestDLEQLengths(t *testing.T) { + suite := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + x := make([]kyber.Scalar, n) + g := make([]kyber.Point, n) + h := make([]kyber.Point, n) + for i := range x { + x[i] = suite.Scalar().Pick(rng) + g[i] = suite.Point().Pick(rng) + h[i] = suite.Point().Pick(rng) + } + // Remove an element to make the test fail + x = append(x[:5], x[6:]...) + _, _, _, err := NewDLEQProofBatch(suite, g, h, x) + require.Equal(t, err, errorDifferentLengths) +} diff --git a/kyber/proof/hash.go b/kyber/proof/hash.go new file mode 100644 index 0000000000..8f1aa508ef --- /dev/null +++ b/kyber/proof/hash.go @@ -0,0 +1,154 @@ +package proof + +import ( + "bytes" + "crypto/cipher" + "fmt" + "io" + + "go.dedis.ch/kyber/v3" +) + +// Hash-based noninteractive Sigma-protocol prover context +type hashProver struct { + suite Suite + proof bytes.Buffer + msg bytes.Buffer + pubrand kyber.XOF + prirand io.Reader +} + +// cipherStreamReader adds a Read method onto a cipher.Stream, +// so that it can be used as an io.Reader. +type cipherStreamReader struct { + cipher.Stream +} + +func (s *cipherStreamReader) Read(in []byte) (int, error) { + x := make([]byte, len(in)) + s.XORKeyStream(x, x) + copy(in, x) + return len(in), nil +} + +func newHashProver(suite Suite, protoName string) *hashProver { + var sc hashProver + sc.suite = suite + sc.pubrand = suite.XOF([]byte(protoName)) + sc.prirand = &cipherStreamReader{suite.RandomStream()} + return &sc +} + +func (c *hashProver) Put(message interface{}) error { + return c.suite.Write(&c.msg, message) +} + +func (c *hashProver) consumeMsg() { + if c.msg.Len() > 0 { + + // Stir the message into the public randomness pool + buf := c.msg.Bytes() + c.pubrand.Reseed() + c.pubrand.Write(buf) + + // Append the current message data to the proof + c.proof.Write(buf) + c.msg.Reset() + } +} + +// Get public randomness that depends on every bit in the proof so far. +func (c *hashProver) PubRand(data ...interface{}) error { + c.consumeMsg() + return c.suite.Read(c.pubrand, data...) +} + +// Get private randomness +func (c *hashProver) PriRand(data ...interface{}) error { + if err := c.suite.Read(c.prirand, data...); err != nil { + return fmt.Errorf("error reading random stream: %v", err.Error()) + } + return nil +} + +// Obtain the encoded proof once the Sigma protocol is complete. +func (c *hashProver) Proof() []byte { + c.consumeMsg() + return c.proof.Bytes() +} + +// Noninteractive Sigma-protocol verifier context +type hashVerifier struct { + suite Suite + proof bytes.Buffer // Buffer with which to read the proof + prbuf []byte // Byte-slice underlying proof buffer + pubrand kyber.XOF +} + +func newHashVerifier(suite Suite, protoName string, + proof []byte) (*hashVerifier, error) { + var c hashVerifier + if _, err := c.proof.Write(proof); err != nil { + return nil, err + } + c.suite = suite + c.prbuf = c.proof.Bytes() + c.pubrand = suite.XOF([]byte(protoName)) + return &c, nil +} + +func (c *hashVerifier) consumeMsg() { + l := len(c.prbuf) - c.proof.Len() // How many bytes read? + if l > 0 { + // Stir consumed bytes into the public randomness pool + buf := c.prbuf[:l] + c.pubrand.Reseed() + c.pubrand.Write(buf) + + c.prbuf = c.proof.Bytes() // Reset to remaining bytes + } +} + +// Read structured data from the proof +func (c *hashVerifier) Get(message interface{}) error { + return c.suite.Read(&c.proof, message) +} + +// Get public randomness that depends on every bit in the proof so far. +func (c *hashVerifier) PubRand(data ...interface{}) error { + c.consumeMsg() // Stir in newly-read data + return c.suite.Read(c.pubrand, data...) +} + +// HashProve runs a given Sigma-protocol prover with a ProverContext +// that produces a non-interactive proof via the Fiat-Shamir heuristic. +// Returns a byte-slice containing the noninteractive proof on success, +// or an error in the case of failure. +// +// The optional protocolName is fed into the hash function used in the proof, +// so that a proof generated for a particular protocolName +// will verify successfully only if the verifier uses the same protocolName. +// +// The caller must provide a source of random entropy for the proof; +// this can be random.New() to use fresh random bits, or a +// pseudorandom stream based on a secret seed to create +// deterministically reproducible proofs. +func HashProve(suite Suite, protocolName string, prover Prover) ([]byte, error) { + ctx := newHashProver(suite, protocolName) + if e := (func(ProverContext) error)(prover)(ctx); e != nil { + return nil, e + } + return ctx.Proof(), nil +} + +// HashVerify computes a hash-based noninteractive proof generated with HashProve. +// The suite and protocolName must be the same as those given to HashProve. +// Returns nil if the proof checks out, or an error on any failure. +func HashVerify(suite Suite, protocolName string, + verifier Verifier, proof []byte) error { + ctx, err := newHashVerifier(suite, protocolName, proof) + if err != nil { + return err + } + return (func(VerifierContext) error)(verifier)(ctx) +} diff --git a/kyber/proof/hash_test.go b/kyber/proof/hash_test.go new file mode 100644 index 0000000000..4fb355ffbb --- /dev/null +++ b/kyber/proof/hash_test.go @@ -0,0 +1,167 @@ +package proof + +import ( + "encoding/hex" + "fmt" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +// This example shows how to build classic ElGamal-style digital signatures +// using the Camenisch/Stadler proof framework and HashProver. +func Example_hashProve1() { + + // Crypto setup + rand := blake2xb.New([]byte("example")) + suite := edwards25519.NewBlakeSHA256Ed25519WithRand(rand) + B := suite.Point().Base() // standard base point + + // Create a public/private keypair (X,x) + x := suite.Scalar().Pick(suite.RandomStream()) // create a private key x + X := suite.Point().Mul(x, nil) // corresponding public key X + + // Generate a proof that we know the discrete logarithm of X. + M := "Hello World!" // message we want to sign + rep := Rep("X", "x", "B") + sec := map[string]kyber.Scalar{"x": x} + pub := map[string]kyber.Point{"B": B, "X": X} + prover := rep.Prover(suite, sec, pub, nil) + proof, _ := HashProve(suite, M, prover) + fmt.Print("Signature:\n" + hex.Dump(proof)) + + // Verify the signature against the correct message M. + verifier := rep.Verifier(suite, pub) + err := HashVerify(suite, M, verifier, proof) + if err != nil { + fmt.Println("signature failed to verify: ", err) + return + } + fmt.Println("Signature verified against correct message M.") + + // Now verify the signature against the WRONG message. + BAD := "Goodbye World!" + verifier = rep.Verifier(suite, pub) + err = HashVerify(suite, BAD, verifier, proof) + fmt.Println("Signature verify against wrong message: " + err.Error()) + + // Output: + // Signature: + // 00000000 e9 a2 da f4 9d 7c e2 25 35 be 0a 15 78 9c ea ca |.....|.%5...x...| + // 00000010 a7 1e 6e d6 26 c3 40 ed 0d 3d 71 d4 a9 ef 55 3b |..n.&.@..=q...U;| + // 00000020 64 76 55 7b 3c 63 20 d8 4b 29 3a 1c 7f 44 59 ad |dvU{| + // 00000040 e3 bd 92 b2 f8 f5 85 97 c4 dd 39 f7 a0 b6 ef b1 |..........9.....| + // 00000050 65 c6 53 80 e4 78 07 52 62 a5 0b a5 f1 0b 33 2b |e.S..x.Rb.....3+| + // 00000060 c8 f5 43 9b 1c bf c2 1a 4a 5b ea b0 e9 18 d1 db |..C.....J[......| + // 00000070 a3 57 eb e0 5b d4 99 0e af f2 10 d4 29 a9 0e 43 |.W..[.......)..C| + // 00000080 fd 20 a1 42 01 ef 68 a0 43 64 70 f4 f9 09 0f 77 |. .B..h.Cdp....w| + // 00000090 b3 b0 82 0a 31 8a 66 41 a8 d0 f4 5f 1e da 6e 63 |....1.fA..._..nc| + // 000000a0 a0 46 74 75 86 6f 3e 85 52 f0 74 6c 74 3b 00 1b |.Ftu.o>.R.tlt;..| + // 000000b0 b2 4b 93 95 33 1d 9e 6a 96 43 e5 e2 30 46 6e e5 |.K..3..j.C..0Fn.| + // 000000c0 2b e0 be 8d 56 55 1a d1 6e 11 21 fc 20 3e 0f 5f |+...VU..n.!. >._| + // 000000d0 4d 97 a9 bf 1a 28 27 6d 3b 71 04 e1 c0 86 96 08 |M....('m;q......| + // 000000e0 8d 0e c0 14 e3 eb 8b e9 16 40 29 60 ab bd e6 1a |.........@)`....| + // 000000f0 68 54 5e 29 c8 85 05 bc 4a 27 83 d9 32 cc 74 0f |hT^)....J'..2.t.| + // 00000100 5e 16 30 25 e2 d6 35 2a d4 3e b5 07 1f d4 0a eb |^.0%..5*.>......| + // 00000110 5d ef 3b 84 35 39 90 0c 3a 02 bb ee c7 9a e7 09 |].;.59..:.......| + // 00000120 d1 cc 1e e1 f4 3b 88 52 e5 99 ed 50 d7 66 b5 76 |.....;.R...P.f.v| + // 00000130 59 6c c1 66 98 07 e5 73 e7 b8 fe 48 43 a0 74 09 |Yl.f...s...HC.t.| + // 00000140 84 9a 7b ec 21 aa ff c7 fc 79 c6 8f f4 23 82 e7 |..{.!....y...#..| + // 00000150 d3 71 69 20 d6 94 27 ef 11 0b 4c a5 79 54 1f 09 |.qi ..'...L.yT..| + // 00000160 6b ec 50 c2 1f 98 38 ea a7 02 da ca aa 1b 6b 39 |k.P...8.......k9| + // 00000170 70 b8 35 6c fe 03 1f b0 08 42 e0 5d b2 5e 40 04 |p.5l.....B.].^@.| + // Linkable Ring Signature verified. +} diff --git a/kyber/proof/proof.go b/kyber/proof/proof.go new file mode 100644 index 0000000000..ec343f45b5 --- /dev/null +++ b/kyber/proof/proof.go @@ -0,0 +1,769 @@ +// Package proof implements generic support for Sigma-protocols +// and discrete logarithm proofs in the Camenisch/Stadler framework. +// For the cryptographic foundations of this framework see +// "Proof Systems for General Statements about Discrete Logarithms" at +// ftp://ftp.inf.ethz.ch/pub/crypto/publications/CamSta97b.pdf. +package proof + +import ( + "errors" + + "go.dedis.ch/kyber/v3" +) + +// Suite defines the functionalities needed for this package to operate +// correctly. It provides a general abstraction to easily change the underlying +// implementations. +type Suite interface { + kyber.Group + kyber.HashFactory + kyber.Encoding + kyber.XOFFactory + kyber.Random +} + +/* +A Predicate is a composable logic expression in a knowledge proof system, +representing a "knowledge specification set" in Camenisch/Stadler terminology. +Atomic predicates in this system are statements of the form P=x1*B1+...+xn+Bn, +indicating the prover knows secrets x1,...,xn that make the statement true, +where P and B1,...,Bn are public points known to the verifier. +These atomic Rep (representation) predicates may be combined +with logical And and Or combinators to form composite statements. +Predicate objects, once created, are immutable and safe to share +or reuse for any number of proofs and verifications. + +After constructing a Predicate using the Rep, And, and Or functions below, +the caller invokes Prover() to create a Sigma-protocol prover. +Prover() requires maps defining the values of both the Scalar variables +and the public Point variables that the Predicate refers to. +If the statement contains logical Or operators, the caller must also pass +a map containing branch choices for each Or predicate +in the "proof-obligated path" down through the Or predicates. +See the examples provded for the Or function for more details. + +Similarly, the caller may invoke Verifier() to create +a Sigma-protocol verifier for the predicate. +The caller must pass a map defining the values +of the public Point variables that the proof refers to. +The verifier need not be provided any secrets or branch choices, of course. +(If the verifier needed those then they wouldn't be secret, would they?) + +Currently we require that all Or operators be above all And operators +in the expression - i.e., Or-of-And combinations are allowed, +but no And-of-Or predicates. +We could rewrite expressions into this form as Camenisch/Stadler suggest, +but that could run a risk of unexpected exponential blowup in the worst case. +We could avoid this risk by not rewriting the expression tree, +but instead generating Pedersen commits for variables that need to "cross" +from one OR-domain to another non-mutually-exclusive one. +For now we simply require expressions to be in the appropriate form. +*/ +type Predicate interface { + + // Create a Prover proving the statement this Predicate represents. + Prover(suite Suite, secrets map[string]kyber.Scalar, + points map[string]kyber.Point, choice map[Predicate]int) Prover + + // Create a Verifier for the statement this Predicate represents. + Verifier(suite Suite, points map[string]kyber.Point) Verifier + + // Produce a human-readable string representation of the predicate. + String() string + + // precedence-sensitive helper stringifier. + precString(prec int) string + + // prover/verifier: enumerate the variables named in a predicate + enumVars(prf *proof) + + // prover: recursively produce all commitments + commit(prf *proof, w kyber.Scalar, v []kyber.Scalar) error + + // prover: given challenge, recursively produce all responses + respond(prf *proof, c kyber.Scalar, r []kyber.Scalar) error + + // verifier: get all the commitments required in this predicate, + // and fill the r slice with empty secrets for responses needed. + getCommits(prf *proof, r []kyber.Scalar) error + + // verifier: check all commitments against challenges and responses + verify(prf *proof, c kyber.Scalar, r []kyber.Scalar) error +} + +// stringification precedence levels +const ( + precNone = iota + precOr + precAnd + precAtom +) + +// Internal prover/verifier state +type proof struct { + s Suite + + nsvars int // number of Scalar variables + npvars int // number of Point variables + svar, pvar []string // Scalar and Point variable names + sidx, pidx map[string]int // Maps from strings to variable indexes + + pval map[string]kyber.Point // values of public Point variables + + // prover-specific state + pc ProverContext + sval map[string]kyber.Scalar // values of private Scalar variables + choice map[Predicate]int // OR branch choices set by caller + pp map[Predicate]*proverPred // per-predicate prover state + + // verifier-specific state + vc VerifierContext + vp map[Predicate]*verifierPred // per-predicate verifier state +} +type proverPred struct { + w kyber.Scalar // secret pre-challenge + v []kyber.Scalar // secret blinding factor for each variable + wi []kyber.Scalar // OR predicates: individual sub-challenges +} +type verifierPred struct { + V kyber.Point // public commitment produced by verifier + r []kyber.Scalar // per-variable responses produced by verifier +} + +////////// Rep predicate ////////// + +// A term describes a point-multiplication term in a representation expression. +type term struct { + S string // Scalar multiplier for this term + B string // Generator for this term +} + +type repPred struct { + P string // Public point of which a representation is known + T []term // Terms comprising the known representation +} + +// Rep creates a predicate stating that the prover knows +// a representation of a point P with respect to +// one or more secrets and base point pairs. +// +// In its simplest usage, Rep indicates that the prover knows a secret x +// that is the (elliptic curve) discrete logarithm of a public point P +// with respect to a well-known base point B: +// +// Rep(P,x,B) +// +// Rep can take any number of (Scalar,Base) variable name pairs, however. +// A Rep statement of the form Rep(P,x1,B1,...,xn,Bn) +// indicates that the prover knows secrets x1,...,xn +// such that point P is the sum x1*B1+...+xn*Bn. +// +func Rep(P string, SB ...string) Predicate { + if len(SB)&1 != 0 { + panic("mismatched Scalar") + } + t := make([]term, len(SB)/2) + for i := range t { + t[i].S = SB[i*2] + t[i].B = SB[i*2+1] + } + return &repPred{P, t} +} + +// Return a string representation of this proof-of-representation predicate, +// mainly for debugging. +func (rp *repPred) String() string { + return rp.precString(precNone) +} + +func (rp *repPred) precString(prec int) string { + s := rp.P + "=" + for i := range rp.T { + if i > 0 { + s += "+" + } + t := &rp.T[i] + s += t.S + s += "*" + s += t.B + } + return s +} + +func (rp *repPred) enumVars(prf *proof) { + prf.enumPointVar(rp.P) + for i := range rp.T { + prf.enumScalarVar(rp.T[i].S) + prf.enumPointVar(rp.T[i].B) + } +} + +func (rp *repPred) commit(prf *proof, w kyber.Scalar, pv []kyber.Scalar) error { + + // Create per-predicate prover state + v := prf.makeScalars(pv) + pp := &proverPred{w, v, nil} + prf.pp[rp] = pp + + // Compute commit V=wY+v1G1+...+vkGk + V := prf.s.Point() + if w != nil { // We're on a non-obligated branch + V.Mul(w, prf.pval[rp.P]) + } else { // We're on a proof-obligated branch, so w=0 + V.Null() + } + P := prf.s.Point() + for i := 0; i < len(rp.T); i++ { + t := rp.T[i] // current term + s := prf.sidx[t.S] + + // Choose a blinding secret the first time + // we encounter each variable + if v[s] == nil { + v[s] = prf.s.Scalar() + prf.pc.PriRand(v[s]) + } + P.Mul(v[s], prf.pval[t.B]) + V.Add(V, P) + } + + // Encode and send the commitment to the verifier + return prf.pc.Put(V) +} + +func (rp *repPred) respond(prf *proof, c kyber.Scalar, + pr []kyber.Scalar) error { + pp := prf.pp[rp] + + // Create a response array for this OR-domain if not done already + r := prf.makeScalars(pr) + + for i := range rp.T { + t := rp.T[i] // current term + s := prf.sidx[t.S] + + // Produce a correct response for each variable + // the first time we encounter that variable. + if r[s] == nil { + if pp.w != nil { + // We're on a non-proof-obligated branch: + // w was our challenge, v[s] is our response. + r[s] = pp.v[s] + continue + } + + // We're on a proof-obligated branch, + // so we need to calculate the correct response + // as r = v-cx where x is the secret variable + ri := prf.s.Scalar() + ri.Mul(c, prf.sval[t.S]) + ri.Sub(pp.v[s], ri) + r[s] = ri + } + } + + // Send our responses if we created the array (i.e., if pr == nil) + return prf.sendResponses(pr, r) +} + +func (rp *repPred) getCommits(prf *proof, pr []kyber.Scalar) error { + + // Create per-predicate verifier state + V := prf.s.Point() + r := prf.makeScalars(pr) + vp := &verifierPred{V, r} + prf.vp[rp] = vp + + // Get the commitment for this representation + if e := prf.vc.Get(vp.V); e != nil { + return e + } + + // Fill in the r vector with the responses we'll need. + for i := range rp.T { + t := rp.T[i] // current term + s := prf.sidx[t.S] + if r[s] == nil { + r[s] = prf.s.Scalar() + } + } + return nil +} + +func (rp *repPred) verify(prf *proof, c kyber.Scalar, pr []kyber.Scalar) error { + vp := prf.vp[rp] + r := vp.r + + // Get the needed responses if a parent didn't already + if e := prf.getResponses(pr, r); e != nil { + return e + } + + // Recompute commit V=cY+r1G1+...+rkGk + V := prf.s.Point() + V.Mul(c, prf.pval[rp.P]) + P := prf.s.Point() + for i := 0; i < len(rp.T); i++ { + t := rp.T[i] // current term + s := prf.sidx[t.S] + P.Mul(r[s], prf.pval[t.B]) + V.Add(V, P) + } + if !V.Equal(vp.V) { + return errors.New("invalid proof: commit mismatch") + } + + return nil +} + +func (rp *repPred) Prover(suite Suite, secrets map[string]kyber.Scalar, + points map[string]kyber.Point, + choice map[Predicate]int) Prover { + return proof{}.init(suite, rp).prover(rp, secrets, points, choice) +} + +func (rp *repPred) Verifier(suite Suite, + points map[string]kyber.Point) Verifier { + return proof{}.init(suite, rp).verifier(rp, points) +} + +////////// And predicate ////////// + +type andPred []Predicate + +// And predicate states that all of the constituent sub-predicates are true. +// And predicates may contain Rep predicates and/or other And predicates. +func And(sub ...Predicate) Predicate { + and := andPred(sub) + return &and +} + +// Return a string representation of this AND predicate, mainly for debugging. +func (ap *andPred) String() string { + return ap.precString(precNone) +} + +func (ap *andPred) precString(prec int) string { + sub := []Predicate(*ap) + s := sub[0].precString(precAnd) + for i := 1; i < len(sub); i++ { + s = s + " && " + sub[i].precString(precAnd) + } + if prec != precNone && prec != precAnd { + s = "(" + s + ")" + } + return s +} + +func (ap *andPred) enumVars(prf *proof) { + sub := []Predicate(*ap) + for i := range sub { + sub[i].enumVars(prf) + } +} + +func (ap *andPred) commit(prf *proof, w kyber.Scalar, pv []kyber.Scalar) error { + sub := []Predicate(*ap) + + // Create per-predicate prover state + v := prf.makeScalars(pv) + //pp := proverPred{w,v,nil} + //prf.pp[ap] = pp + + // Recursively generate commitments + for i := 0; i < len(sub); i++ { + if e := sub[i].commit(prf, w, v); e != nil { + return e + } + } + + return nil +} + +func (ap *andPred) respond(prf *proof, c kyber.Scalar, pr []kyber.Scalar) error { + sub := []Predicate(*ap) + //pp := prf.pp[ap] + + // Recursively compute responses in all sub-predicates + r := prf.makeScalars(pr) + for i := range sub { + if e := sub[i].respond(prf, c, r); e != nil { + return e + } + } + return prf.sendResponses(pr, r) +} + +func (ap *andPred) getCommits(prf *proof, pr []kyber.Scalar) error { + sub := []Predicate(*ap) + + // Create per-predicate verifier state + r := prf.makeScalars(pr) + vp := &verifierPred{nil, r} + prf.vp[ap] = vp + + for i := range sub { + if e := sub[i].getCommits(prf, r); e != nil { + return e + } + } + return nil +} + +func (ap *andPred) verify(prf *proof, c kyber.Scalar, pr []kyber.Scalar) error { + sub := []Predicate(*ap) + vp := prf.vp[ap] + r := vp.r + + if e := prf.getResponses(pr, r); e != nil { + return e + } + for i := range sub { + if e := sub[i].verify(prf, c, r); e != nil { + return e + } + } + return nil +} + +func (ap *andPred) Prover(suite Suite, secrets map[string]kyber.Scalar, + points map[string]kyber.Point, + choice map[Predicate]int) Prover { + return proof{}.init(suite, ap).prover(ap, secrets, points, choice) +} + +func (ap *andPred) Verifier(suite Suite, + points map[string]kyber.Point) Verifier { + return proof{}.init(suite, ap).verifier(ap, points) +} + +////////// Or predicate ////////// + +type orPred []Predicate + +// Or predicate states that the prover knows +// at least one of the sub-predicates to be true, +// but the proof does not reveal any information about which. +func Or(sub ...Predicate) Predicate { + or := orPred(sub) + return &or +} + +// Return a string representation of this OR predicate, mainly for debugging. +func (op *orPred) String() string { + return op.precString(precNone) +} + +func (op *orPred) precString(prec int) string { + sub := []Predicate(*op) + s := sub[0].precString(precOr) + for i := 1; i < len(sub); i++ { + s = s + " || " + sub[i].precString(precOr) + } + if prec != precNone && prec != precOr { + s = "(" + s + ")" + } + return s +} + +func (op *orPred) enumVars(prf *proof) { + sub := []Predicate(*op) + for i := range sub { + sub[i].enumVars(prf) + } +} + +func (op *orPred) commit(prf *proof, w kyber.Scalar, pv []kyber.Scalar) error { + sub := []Predicate(*op) + if pv != nil { // only happens within an AND expression + return errors.New("can't have OR predicates within AND predicates") + } + + // Create per-predicate prover state + wi := make([]kyber.Scalar, len(sub)) + pp := &proverPred{w, nil, wi} + prf.pp[op] = pp + + // Choose pre-challenges for our subs. + if w == nil { + // We're on a proof-obligated branch; + // choose random pre-challenges for only non-obligated subs. + choice, ok := prf.choice[op] + if !ok || choice < 0 || choice >= len(sub) { + return errors.New("no choice of proof branch for OR-predicate " + + op.String()) + } + for i := 0; i < len(sub); i++ { + if i != choice { + wi[i] = prf.s.Scalar() + prf.pc.PriRand(wi[i]) + } // else wi[i] == nil for proof-obligated sub + } + } else { + // Since w != nil, we're in a non-obligated branch, + // so choose random pre-challenges for all subs + // such that they add up to the master pre-challenge w. + last := len(sub) - 1 // index of last sub + wl := prf.s.Scalar().Set(w) + for i := 0; i < last; i++ { // choose all but last + wi[i] = prf.s.Scalar() + prf.pc.PriRand(wi[i]) + wl.Sub(wl, wi[i]) + } + wi[last] = wl + } + + // Now recursively choose commitments within each sub + for i := 0; i < len(sub); i++ { + // Fresh variable-blinding secrets for each pre-commitment + if e := sub[i].commit(prf, wi[i], nil); e != nil { + return e + } + } + + return nil +} + +func (op *orPred) respond(prf *proof, c kyber.Scalar, pr []kyber.Scalar) error { + sub := []Predicate(*op) + pp := prf.pp[op] + if pr != nil { + return errors.New("OR predicates can't be nested in anything else") + } + + ci := pp.wi + if pp.w == nil { + // Calculate the challenge for the proof-obligated subtree + cs := prf.s.Scalar().Set(c) + choice := prf.choice[op] + for i := 0; i < len(sub); i++ { + if i != choice { + cs.Sub(cs, ci[i]) + } + } + ci[choice] = cs + } + + // If there's more than one choice, send all our sub-challenges. + if len(sub) > 1 { + if e := prf.pc.Put(ci); e != nil { + return e + } + } + + // Recursively compute responses in all subtrees + for i := range sub { + if e := sub[i].respond(prf, ci[i], nil); e != nil { + return e + } + } + + return nil +} + +// Get from the verifier all the commitments needed for this predicate +func (op *orPred) getCommits(prf *proof, pr []kyber.Scalar) error { + sub := []Predicate(*op) + for i := range sub { + if e := sub[i].getCommits(prf, nil); e != nil { + return e + } + } + return nil +} + +func (op *orPred) verify(prf *proof, c kyber.Scalar, pr []kyber.Scalar) error { + sub := []Predicate(*op) + if pr != nil { + return errors.New("OR predicates can't be in anything else") + } + + // Get the prover's sub-challenges + nsub := len(sub) + ci := make([]kyber.Scalar, nsub) + if nsub > 1 { + if e := prf.vc.Get(ci); e != nil { + return e + } + + // Make sure they add up to the parent's composite challenge + csum := prf.s.Scalar().Zero() + for i := 0; i < nsub; i++ { + csum.Add(csum, ci[i]) + } + if !csum.Equal(c) { + return errors.New("invalid proof: bad sub-challenges") + } + + } else { // trivial single-sub OR + ci[0] = c + } + + // Recursively verify all subs + for i := range sub { + if e := sub[i].verify(prf, ci[i], nil); e != nil { + return e + } + } + + return nil +} + +func (op *orPred) Prover(suite Suite, secrets map[string]kyber.Scalar, + points map[string]kyber.Point, + choice map[Predicate]int) Prover { + return proof{}.init(suite, op).prover(op, secrets, points, choice) +} + +func (op *orPred) Verifier(suite Suite, + points map[string]kyber.Point) Verifier { + return proof{}.init(suite, op).verifier(op, points) +} + +/* +type lin struct { + a1,a2,b kyber.Scalar + x1,x2 PriVar +} +*/ + +// Construct a predicate asserting a linear relationship a1x1+a2x2=b, +// where a1,a2,b are public values and x1,x2 are secrets. +/* +func (p *Prover) Linear(a1,a2,b kyber.Scalar, x1,x2 PriVar) { + return &lin{a1,a2,b,x1,x2} +} +*/ + +func (prf proof) init(suite Suite, pred Predicate) *proof { + prf.s = suite + + // Enumerate all the variables in a consistent order. + // Reserve variable index 0 for convenience. + prf.svar = []string{""} + prf.pvar = []string{""} + prf.sidx = make(map[string]int) + prf.pidx = make(map[string]int) + pred.enumVars(&prf) + prf.nsvars = len(prf.svar) + prf.npvars = len(prf.pvar) + + return &prf +} + +func (prf *proof) enumScalarVar(name string) { + if prf.sidx[name] == 0 { + prf.sidx[name] = len(prf.svar) + prf.svar = append(prf.svar, name) + } +} + +func (prf *proof) enumPointVar(name string) { + if prf.pidx[name] == 0 { + prf.pidx[name] = len(prf.pvar) + prf.pvar = append(prf.pvar, name) + } +} + +// Make a response-array if that wasn't already done in a parent predicate. +func (prf *proof) makeScalars(pr []kyber.Scalar) []kyber.Scalar { + if pr == nil { + return make([]kyber.Scalar, prf.nsvars) + } + return pr +} + +// Transmit our response-array if a corresponding makeScalars() created it. +func (prf *proof) sendResponses(pr []kyber.Scalar, r []kyber.Scalar) error { + if pr == nil { + for i := range r { + // Send responses only for variables + // that were used in this OR-domain. + if r[i] != nil { + if e := prf.pc.Put(r[i]); e != nil { + return e + } + } + } + } + return nil +} + +// In the verifier, get the responses at the top of an OR-domain, +// if a corresponding makeScalars() call created it. +func (prf *proof) getResponses(pr []kyber.Scalar, r []kyber.Scalar) error { + if pr == nil { + for i := range r { + if r[i] != nil { + if e := prf.vc.Get(r[i]); e != nil { + return e + } + } + } + } + return nil +} + +func (prf *proof) prove(p Predicate, sval map[string]kyber.Scalar, + pval map[string]kyber.Point, + choice map[Predicate]int, pc ProverContext) error { + prf.pc = pc + prf.sval = sval + prf.pval = pval + prf.choice = choice + prf.pp = make(map[Predicate]*proverPred) + + // Generate all commitments + if e := p.commit(prf, nil, nil); e != nil { + return e + } + + // Generate top-level challenge from public randomness + c := prf.s.Scalar() + if e := pc.PubRand(c); e != nil { + return e + } + + // Generate all responses based on master challenge + return p.respond(prf, c, nil) +} + +func (prf *proof) verify(p Predicate, pval map[string]kyber.Point, + vc VerifierContext) error { + prf.vc = vc + prf.pval = pval + prf.vp = make(map[Predicate]*verifierPred) + + // Get the commitments from the verifier, + // and calculate the sets of responses we'll need for each OR-domain. + if e := p.getCommits(prf, nil); e != nil { + return e + } + + // Produce the top-level challenge + c := prf.s.Scalar() + if e := vc.PubRand(c); e != nil { + return e + } + + // Check all the responses and sub-challenges against the commitments. + return p.verify(prf, c, nil) +} + +// Produce a higher-order Prover embodying a given proof predicate. +func (prf *proof) prover(p Predicate, sval map[string]kyber.Scalar, + pval map[string]kyber.Point, + choice map[Predicate]int) Prover { + + return Prover(func(ctx ProverContext) error { + return prf.prove(p, sval, pval, choice, ctx) + }) +} + +// Produce a higher-order Verifier embodying a given proof predicate. +func (prf *proof) verifier(p Predicate, pval map[string]kyber.Point) Verifier { + + return Verifier(func(ctx VerifierContext) error { + return prf.verify(p, pval, ctx) + }) +} diff --git a/kyber/proof/proof_test.go b/kyber/proof/proof_test.go new file mode 100644 index 0000000000..6ca8d1797d --- /dev/null +++ b/kyber/proof/proof_test.go @@ -0,0 +1,248 @@ +package proof + +import ( + "encoding/hex" + "fmt" + "testing" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +func TestRep(t *testing.T) { + rand := blake2xb.New([]byte("seed")) + suite := edwards25519.NewBlakeSHA256Ed25519WithRand(rand) + + x := suite.Scalar().Pick(rand) + y := suite.Scalar().Pick(rand) + B := suite.Point().Base() + X := suite.Point().Mul(x, nil) + Y := suite.Point().Mul(y, X) + R := suite.Point().Add(X, Y) + + choice := make(map[Predicate]int) + + // Simple single-secret predicate: prove X=x*B + log := Rep("X", "x", "B") + + // Two-secret representation: prove R=x*B+y*X + rep := Rep("R", "x", "B", "y", "X") + + // Make an and-predicate + and := And(log, rep) + andx := And(and) + + // Make up a couple incorrect facts + falseLog := Rep("Y", "x", "B") + falseRep := Rep("R", "x", "B", "y", "B") + + falseAnd := And(falseLog, falseRep) + + or1 := Or(falseAnd, andx) + choice[or1] = 1 + or1x := Or(or1) // test trivial case + choice[or1x] = 0 + + or2a := Rep("B", "y", "X") + or2b := Rep("R", "x", "R") + or2 := Or(or2a, or2b) + or2x := Or(or2) // test trivial case + + pred := Or(or1x, or2x) + choice[pred] = 0 + + sval := map[string]kyber.Scalar{"x": x, "y": y} + pval := map[string]kyber.Point{"B": B, "X": X, "Y": Y, "R": R} + prover := pred.Prover(suite, sval, pval, choice) + proof, err := HashProve(suite, "TEST", prover) + if err != nil { + t.Fatal("prover: " + err.Error()) + } + + verifier := pred.Verifier(suite, pval) + if err := HashVerify(suite, "TEST", verifier, proof); err != nil { + t.Fatal("verify: " + err.Error()) + } +} + +// This code creates a simple discrete logarithm knowledge proof. +// In particular, that the prover knows a secret x +// that is the elliptic curve discrete logarithm of a point X +// with respect to some base B: i.e., X=x*B. +// If we take X as a public key and x as its corresponding private key, +// then this constitutes a "proof of ownership" of the public key X. +func Example_rep1() { + pred := Rep("X", "x", "B") + fmt.Println(pred.String()) + // Output: X=x*B +} + +// This example shows how to generate and verify noninteractive proofs +// of the statement in the example above, i.e., +// a proof of ownership of public key X. +func Example_rep2() { + pred := Rep("X", "x", "B") + fmt.Println(pred.String()) + + // Crypto setup + rand := blake2xb.New([]byte("example")) + suite := edwards25519.NewBlakeSHA256Ed25519WithRand(rand) + B := suite.Point().Base() // standard base point + + // Create a public/private keypair (X,x) + x := suite.Scalar().Pick(rand) // create a private key x + X := suite.Point().Mul(x, nil) // corresponding public key X + + // Generate a proof that we know the discrete logarithm of X. + sval := map[string]kyber.Scalar{"x": x} + pval := map[string]kyber.Point{"B": B, "X": X} + prover := pred.Prover(suite, sval, pval, nil) + proof, _ := HashProve(suite, "TEST", prover) + fmt.Print("Proof:\n" + hex.Dump(proof)) + + // Verify this knowledge proof. + verifier := pred.Verifier(suite, pval) + err := HashVerify(suite, "TEST", verifier, proof) + if err != nil { + fmt.Println("Proof failed to verify: ", err) + return + } + fmt.Println("Proof verified.") + + // Output: + // X=x*B + // Proof: + // 00000000 e9 a2 da f4 9d 7c e2 25 35 be 0a 15 78 9c ea ca |.....|.%5...x...| + // 00000010 a7 1e 6e d6 26 c3 40 ed 0d 3d 71 d4 a9 ef 55 3b |..n.&.@..=q...U;| + // 00000020 c1 84 20 a6 b7 79 86 9c f8 dd 09 82 1e 48 a9 00 |.. ..y.......H..| + // 00000030 3e f3 68 66 3f a0 58 f9 88 df b4 35 1b 2f 72 0d |>.hf?.X....5./r.| + // Proof verified. +} + +// This code creates a predicate stating that the prover knows a representation +// of point X with respect to two different bases B1 and B2. +// This means the prover knows two secrets x1 and x2 +// such that X=x1*B1+x2*B2. +// +// Point X might constitute a Pedersen commitment, for example, +// where x1 is the value being committed to and x2 is a random blinding factor. +// Assuming the discrete logarithm problem is hard in the relevant group +// and the logarithmic relationship between bases B1 and B2 is unknown - +// which we would be true if B1 and B2 are chosen at random, for example - +// then a prover who has committed to point P +// will later be unable to "open" the commitment +// using anything other than secrets x1 and x2. +// The prover can also prove that one of the secrets (say x1) +// is equal to a secret used in the representation of some other point, +// while leaving the other secret (x2) unconstrained. +// +// If the prover does know the relationship between B1 and B2, however, +// then X does not serve as a useful commitment: +// the prover can trivially compute the x1 corresponding to an arbitrary x2. +// +func Example_rep3() { + pred := Rep("X", "x1", "B1", "x2", "B2") + fmt.Println(pred.String()) + // Output: X=x1*B1+x2*B2 +} + +// This code creates an And predicate indicating that +// the prover knows two different secrets x and y, +// such that point X is equal to x*B +// and point Y is equal to y*B. +// This predicate might be used to prove knowledge of +// the private keys corresponding to two public keys X and Y, for example. +func Example_and1() { + pred := And(Rep("X", "x", "B"), Rep("Y", "y", "B")) + fmt.Println(pred.String()) + // Output: X=x*B && Y=y*B +} + +// This code creates an And predicate indicating that +// the prover knows a single secret value x, +// such that point X1 is equal to x*B1 +// and point X2 is equal to x*B2. +// Thus, the prover not only proves knowledge of the discrete logarithm +// of X1 with respect to B1 and of X2 with respect to B2, +// but also proves that those two discrete logarithms are equal. +func Example_and2() { + pred := And(Rep("X1", "x", "B1"), Rep("X2", "x", "B2")) + fmt.Println(pred.String()) + // Output: X1=x*B1 && X2=x*B2 +} + +// This code creates an Or predicate indicating that +// the prover either knows a secret x such that X=x*B, +// or the prover knows a secret y such that Y=y*B. +// This predicate in essence proves knowledge of the private key +// for one of two public keys X or Y, +// without revealing which key the prover owns. +func Example_or1() { + pred := Or(Rep("X", "x", "B"), Rep("Y", "y", "B")) + fmt.Println(pred.String()) + // Output: X=x*B || Y=y*B +} + +// This code shows how to create and verify Or-predicate proofs, +// such as the one above. +// In this case, we know a secret x such that X=x*B, +// but we don't know a secret y such that Y=y*B, +// because we simply pick Y as a random point +// instead of generating it by scalar multiplication. +// (And if the group is cryptographically secure +// we won't find be able to find such a y.) +func Example_or2() { + // Create an Or predicate. + pred := Or(Rep("X", "x", "B"), Rep("Y", "y", "B")) + fmt.Println("Predicate: " + pred.String()) + + // Crypto setup + rand := blake2xb.New([]byte("example")) + suite := edwards25519.NewBlakeSHA256Ed25519WithRand(rand) + B := suite.Point().Base() // standard base point + + // Create a public/private keypair (X,x) and a random point Y + x := suite.Scalar().Pick(rand) // create a private key x + X := suite.Point().Mul(x, nil) // corresponding public key X + Y := suite.Point().Pick(rand) // pick a random point Y + + // We'll need to tell the prover which Or clause is actually true. + // In this case clause 0, the first sub-predicate, is true: + // i.e., we know a secret x such that X=x*B. + choice := make(map[Predicate]int) + choice[pred] = 0 + + // Generate a proof that we know the discrete logarithm of X or Y. + sval := map[string]kyber.Scalar{"x": x} + pval := map[string]kyber.Point{"B": B, "X": X, "Y": Y} + prover := pred.Prover(suite, sval, pval, choice) + proof, _ := HashProve(suite, "TEST", prover) + fmt.Print("Proof:\n" + hex.Dump(proof)) + + // Verify this knowledge proof. + // The verifier doesn't need the secret values or choice map, of course. + verifier := pred.Verifier(suite, pval) + err := HashVerify(suite, "TEST", verifier, proof) + if err != nil { + fmt.Println("Proof failed to verify: " + err.Error()) + } + fmt.Println("Proof verified.") + + // Output: + // Predicate: X=x*B || Y=y*B + // Proof: + // 00000000 44 bb 0f bb 2b 06 29 a6 73 59 0f c1 5a ca de 36 |D...+.).sY..Z..6| + // 00000010 4c c8 15 ed b1 eb 50 d3 d9 d2 9b 31 6c d3 0f 6b |L.....P....1l..k| + // 00000020 a2 a9 bc d2 8c 6d d0 5e 9a 8e d1 8e 04 fb 88 af |.....m.^........| + // 00000030 fb 90 8a 2a 71 ac 34 08 f9 bc 07 78 08 44 40 07 |...*q.4....x.D@.| + // 00000040 ab 1f 36 7e 7b db 50 7d 49 38 34 75 69 07 67 4b |..6~{.P}I84ui.gK| + // 00000050 55 cb 28 f2 50 ad d1 4b 24 d2 d1 44 fe 44 b0 0e |U.(.P..K$..D.D..| + // 00000060 00 e8 d3 8b 37 76 4f 47 d1 4a 93 0c cd df 20 08 |....7vOG.J.... .| + // 00000070 fc 0f ad f9 01 6c 30 c0 02 d4 fa 1b 1f 1c fa 04 |.....l0.........| + // 00000080 6d 2a a7 d8 8e 67 72 87 51 0e 16 72 51 87 99 83 |m*...gr.Q..rQ...| + // 00000090 2e c9 4e a1 ca 20 7d 64 33 04 f5 66 9b d3 74 03 |..N.. }d3..f..t.| + // 000000a0 2b e0 be 8d 56 55 1a d1 6e 11 21 fc 20 3e 0f 5f |+...VU..n.!. >._| + // 000000b0 4d 97 a9 bf 1a 28 27 6d 3b 71 04 e1 c0 86 96 08 |M....('m;q......| + // Proof verified. +} diff --git a/kyber/random.go b/kyber/random.go new file mode 100644 index 0000000000..434d76722f --- /dev/null +++ b/kyber/random.go @@ -0,0 +1,13 @@ +package kyber + +import ( + "crypto/cipher" +) + +// Random is an interface that can be mixed in to local suite definitions. +type Random interface { + // RandomStream returns a cipher.Stream that produces a + // cryptographically random key stream. The stream must + // tolerate being used in multiple goroutines. + RandomStream() cipher.Stream +} diff --git a/kyber/share/dkg/pedersen/dkg.go b/kyber/share/dkg/pedersen/dkg.go new file mode 100644 index 0000000000..756c79a196 --- /dev/null +++ b/kyber/share/dkg/pedersen/dkg.go @@ -0,0 +1,715 @@ +// Package dkg implements a general distributed key generation (DKG) framework. +// This package serves two functionalities: (1) to run a fresh new DKG from +// scratch and (2) to reshare old shares to a potentially distinct new set of +// nodes (the "resharing" protocol). The former protocol is described in "A +// threshold cryptosystem without a trusted party" by Torben Pryds Pedersen. +// https://dl.acm.org/citation.cfm?id=1754929. The latter protocol is +// implemented in "Verifiable Secret Redistribution for Threshold Signing +// Schemes", by T. Wong et +// al.(https://www.cs.cmu.edu/~wing/publications/Wong-Wing02b.pdf) +package dkg + +import ( + "errors" + + "go.dedis.ch/kyber/v3" + + "go.dedis.ch/kyber/v3/share" + vss "go.dedis.ch/kyber/v3/share/vss/pedersen" + "go.dedis.ch/kyber/v3/sign/schnorr" +) + +// Suite wraps the functionalities needed by the dkg package +type Suite vss.Suite + +// Config holds all required information to run a fresh DKG protocol or a +// resharing protocol. In the case of a new fresh DKG protocol, one must fill +// the following fields: Suite, Longterm, NewNodes, Threshold (opt). In the case +// of a resharing protocol, one must fill the following: Suite, Longterm, +// OldNodes, NewNodes. If the node using this config is creating new shares +// (i.e. it belongs to the current group), the Share field must be filled in +// with the current share of the node. If the node using this config is a new +// addition and thus has no current share, the PublicCoeffs field be must be +// filled in. +type Config struct { + Suite Suite + + // Longterm is the longterm secret key. + Longterm kyber.Scalar + + // Current group of share holders. It will be nil for new DKG. These nodes + // will have invalid shares after the protocol has been run. To be able to issue + // new shares to a new group, the group member's public key must be inside this + // list and in the Share field. Keys can be disjoint or not with respect to the + // NewNodes list. + OldNodes []kyber.Point + + // PublicCoeffs are the coefficients of the distributed polynomial needed + // during the resharing protocol. The first coefficient is the key. It is + // required for new share holders. It should be nil for a new DKG. + PublicCoeffs []kyber.Point + + // Expected new group of share holders. These public-key designated nodes + // will be in possession of new shares after the protocol has been run. To be a + // receiver of a new share, one's public key must be inside this list. Keys + // can be disjoint or not with respect to the OldNodes list. + NewNodes []kyber.Point + + // Share to refresh. It must be nil for a new node wishing to + // join or create a group. To be able to issue new fresh shares to a new group, + // one's share must be specified here, along with the public key inside the + // OldNodes field. + Share *DistKeyShare + + // New threshold to use if set. Default will be returned by `vss.MinimumT()` + Threshold int +} + +// NewDKGConfig returns a Config that is made for a fresh new DKG run. +func NewDKGConfig(suite Suite, longterm kyber.Scalar, participants []kyber.Point) *Config { + return &Config{ + Suite: suite, + Longterm: longterm, + NewNodes: participants, + OldNodes: participants, + Threshold: vss.MinimumT(len(participants)), + } +} + +// NewReshareConfig returns a new config to use with DistKeyGenerator to run the +// re-sharing protocols between the old nodes and the new nodes, i.e. the future +// share holders. Share must be non-nil for previously enrolled nodes to +// actively issue new shares. The public coefficients, pcoeffs, are needed in +// order for participants in newNodes to be able to verify the validity of newly +// received shares. +func NewReshareConfig(suite Suite, longterm kyber.Scalar, oldNodes, newNodes []kyber.Point, + share *DistKeyShare, pcoeffs []kyber.Point) *Config { + return &Config{ + Suite: suite, + Longterm: longterm, + OldNodes: oldNodes, + NewNodes: newNodes, + Share: share, + PublicCoeffs: pcoeffs, + Threshold: vss.MinimumT(len(newNodes)), + } +} + +// DistKeyGenerator is the struct that runs the DKG protocol. +type DistKeyGenerator struct { + // config driving the behavior of DistKeyGenerator + c *Config + suite Suite + + long kyber.Scalar + pub kyber.Point + dpub *share.PubPoly + dealer *vss.Dealer + // verifiers indexed by dealer index + verifiers map[uint32]*vss.Verifier + // performs the part of the response verification for old nodes + oldAggregators map[uint32]*vss.Aggregator + + // index in the old list of nodes + oidx int + // index in the new list of nodes + nidx int + // old threshold used in the previous DKG + oldT int + // new threshold to use in this round + newT int + // indicates whether we are in the re-sharing protocol or basic DKG + isResharing bool + // indicates whether we are able to issue shares or not + canIssue bool + // Indicates whether we are able to receive a new share or not + canReceive bool + // indicates whether the node holding the pub key is present in the new list + newPresent bool + // indicates whether the node is present in the old list + oldPresent bool +} + +// NewDistKeyHandler takes a Config and returns a DistKeyGenerator that is able +// to drive the DKG or resharing protocol. +func NewDistKeyHandler(c *Config) (*DistKeyGenerator, error) { + if c.NewNodes == nil && c.OldNodes == nil { + return nil, errors.New("dkg: can't run with empty node list") + } + + var isResharing bool + if c.Share != nil || c.PublicCoeffs != nil { + isResharing = true + } + // canReceive is true by default since in the default DKG mode everyone + // participates + var canReceive = true + pub := c.Suite.Point().Mul(c.Longterm, nil) + oidx, oldPresent := findPub(c.OldNodes, pub) + nidx, newPresent := findPub(c.NewNodes, pub) + if !oldPresent && !newPresent { + return nil, errors.New("dkg: public key not found in old list or new list") + } + + var newThreshold int + if c.Threshold != 0 { + newThreshold = c.Threshold + } else { + newThreshold = vss.MinimumT(len(c.NewNodes)) + } + + var dealer *vss.Dealer + var err error + var canIssue bool + if c.Share != nil { + // resharing case + secretCoeff := c.Share.Share.V + dealer, err = vss.NewDealer(c.Suite, c.Longterm, secretCoeff, c.NewNodes, newThreshold) + canIssue = true + } else if !isResharing && newPresent { + // fresh DKG case + secretCoeff := c.Suite.Scalar().Pick(c.Suite.RandomStream()) + dealer, err = vss.NewDealer(c.Suite, c.Longterm, secretCoeff, c.NewNodes, newThreshold) + canIssue = true + c.OldNodes = c.NewNodes + oidx, oldPresent = findPub(c.OldNodes, pub) + } + + var dpub *share.PubPoly + var oldThreshold int + if !newPresent { + // if we are not in the new list of nodes, then we definitely can't + // receive anything + canReceive = false + } else if isResharing && newPresent { + if c.PublicCoeffs == nil && c.Share == nil { + return nil, errors.New("dkg: can't receive new shares without the public polynomial") + } else if c.PublicCoeffs != nil { + dpub = share.NewPubPoly(c.Suite, c.Suite.Point().Base(), c.PublicCoeffs) + } else if c.Share != nil { + // take the commits of the share, no need to duplicate information + c.PublicCoeffs = c.Share.Commits + dpub = share.NewPubPoly(c.Suite, c.Suite.Point().Base(), c.PublicCoeffs) + } + // oldThreshold is only useful in the context of a new share holder, to + // make sure there are enough correct deals from the old nodes. + canReceive = true + oldThreshold = len(c.PublicCoeffs) + } + + return &DistKeyGenerator{ + dealer: dealer, + verifiers: make(map[uint32]*vss.Verifier), + oldAggregators: make(map[uint32]*vss.Aggregator), + suite: c.Suite, + long: c.Longterm, + pub: pub, + canReceive: canReceive, + canIssue: canIssue, + isResharing: isResharing, + dpub: dpub, + oidx: oidx, + nidx: nidx, + c: c, + oldT: oldThreshold, + newT: newThreshold, + newPresent: newPresent, + oldPresent: oldPresent, + }, err +} + +// NewDistKeyGenerator returns a dist key generator ready to create a fresh +// distributed key with the regular DKG protocol. +func NewDistKeyGenerator(suite Suite, longterm kyber.Scalar, participants []kyber.Point, t int) (*DistKeyGenerator, error) { + c := &Config{ + Suite: suite, + Longterm: longterm, + NewNodes: participants, + Threshold: t, + } + return NewDistKeyHandler(c) +} + +// Deals returns all the deals that must be broadcasted to all participants in +// the new list. The deal corresponding to this DKG is already added to this DKG +// and is ommitted from the returned map. To know which participant a deal +// belongs to, loop over the keys as indices in the list of new participants: +// +// for i,dd := range distDeals { +// sendTo(participants[i],dd) +// } +// +// If this method cannot process its own Deal, that indicates a +// severe problem with the configuration or implementation and +// results in a panic. +func (d *DistKeyGenerator) Deals() (map[int]*Deal, error) { + if !d.canIssue { + return nil, nil + } + deals, err := d.dealer.EncryptedDeals() + if err != nil { + return nil, err + } + dd := make(map[int]*Deal) + for i := range d.c.NewNodes { + distd := &Deal{ + Index: uint32(d.oidx), + Deal: deals[i], + } + // sign the deal + buff, err := distd.MarshalBinary() + if err != nil { + return nil, err + } + distd.Signature, err = schnorr.Sign(d.suite, d.long, buff) + if err != nil { + return nil, err + } + + if i == int(d.nidx) && d.canReceive { + if _, ok := d.verifiers[uint32(d.nidx)]; ok { + // already processed our own deal + continue + } + if resp, err := d.ProcessDeal(distd); err != nil { + panic("dkg: cannot process own deal: " + err.Error()) + } else if resp.Response.Status != vss.StatusApproval { + panic("dkg: own deal gave a complaint") + } + continue + } + dd[i] = distd + } + return dd, nil +} + +// ProcessDeal takes a Deal created by Deals() and stores and verifies it. It +// returns a Response to broadcast to every other participant, including the old +// participants. It returns an error in case the deal has already been stored, +// or if the deal is incorrect (see vss.Verifier.ProcessEncryptedDeal). +func (d *DistKeyGenerator) ProcessDeal(dd *Deal) (*Response, error) { + var pub kyber.Point + var ok bool + if d.isResharing { + pub, ok = getPub(d.c.OldNodes, dd.Index) + } else { + pub, ok = getPub(d.c.NewNodes, dd.Index) + } + // public key of the dealer + if !ok { + return nil, errors.New("dkg: dist deal out of bounds index") + } + + // verify signature + buff, err := dd.MarshalBinary() + if err != nil { + return nil, err + } + if err := schnorr.Verify(d.suite, pub, buff, dd.Signature); err != nil { + return nil, err + } + + if _, ok := d.verifiers[dd.Index]; ok { + return nil, errors.New("dkg: already received dist deal from same index") + } + + // verifier receiving the dealer's deal + ver, err := vss.NewVerifier(d.suite, d.long, pub, d.c.NewNodes) + if err != nil { + return nil, err + } + + d.verifiers[dd.Index] = ver + resp, err := ver.ProcessEncryptedDeal(dd.Deal) + if err != nil { + return nil, err + } + + reject := func() (*Response, error) { + idx, present := findPub(d.c.NewNodes, pub) + if present { + d.verifiers[uint32(idx)].UnsafeSetResponseDKG(uint32(idx), vss.StatusComplaint) + } + // indicate to VSS that the new status is complaint, since the check is + // done outside of VSS package control. + d.verifiers[uint32(d.nidx)].UnsafeSetResponseDKG(uint32(d.nidx), vss.StatusComplaint) + resp.Status = vss.StatusComplaint + s, err := schnorr.Sign(d.suite, d.long, resp.Hash(d.suite)) + if err != nil { + return nil, err + } + resp.Signature = s + return &Response{ + Index: dd.Index, + Response: resp, + }, nil + } + + if d.isResharing && d.canReceive { + // verify share integrity wrt to the dist. secret + dealCommits := ver.Commits() + // Check that the received committed share is equal to the one we + // generate from the known public polynomial + expectedPubShare := d.dpub.Eval(int(dd.Index)) + if !expectedPubShare.V.Equal(dealCommits[0]) { + return reject() + } + } + + // if the dealer in the old list is also present in the new list, then set + // his response to approval since he won't issue his own response for his + // own deal + newIdx, found := findPub(d.c.NewNodes, pub) + if found { + d.verifiers[dd.Index].UnsafeSetResponseDKG(uint32(newIdx), vss.StatusApproval) + } + + return &Response{ + Index: dd.Index, + Response: resp, + }, nil +} + +// ProcessResponse takes a response from every other peer. If the response +// designates the deal of another participant than this dkg, this dkg stores it +// and returns nil with a possible error regarding the validity of the response. +// If the response designates a deal this dkg has issued, then the dkg will process +// the response, and returns a justification. +func (d *DistKeyGenerator) ProcessResponse(resp *Response) (*Justification, error) { + if d.isResharing && d.canIssue && !d.newPresent { + return d.processResharingResponse(resp) + } + + v, ok := d.verifiers[resp.Index] + if !ok { + return nil, errors.New("dkg: response received but no deal for it") + } + + if err := v.ProcessResponse(resp.Response); err != nil { + return nil, err + } + + myIdx := uint32(d.oidx) + if !d.canIssue || resp.Index != myIdx { + // no justification if we dont issue deals or the deal's not from us + return nil, nil + } + + j, err := d.dealer.ProcessResponse(resp.Response) + if err != nil { + return nil, err + } + if j == nil { + return nil, nil + } + if err := v.ProcessJustification(j); err != nil { + return nil, err + } + + return &Justification{ + Index: uint32(d.oidx), + Justification: j, + }, nil +} + +// special case when an node that is present in the old list but not in the +// new,i.e. leaving the group, does not have any verifiers since it can't +// receive shares. This function makes some check on the response and returns a +// justification if the response is invalid. +func (d *DistKeyGenerator) processResharingResponse(resp *Response) (*Justification, error) { + agg, present := d.oldAggregators[resp.Index] + if !present { + agg = vss.NewEmptyAggregator(d.suite, d.c.NewNodes) + d.oldAggregators[resp.Index] = agg + } + + err := agg.ProcessResponse(resp.Response) + if int(resp.Index) != d.oidx { + return nil, err + } + + if resp.Response.Status == vss.StatusApproval { + return nil, nil + } + + // status is complaint and it is about our deal + deal, err := d.dealer.PlaintextDeal(int(resp.Response.Index)) + if err != nil { + return nil, errors.New("dkg: resharing response can't get deal. BUG - REPORT") + } + j := &Justification{ + Index: uint32(d.oidx), + Justification: &vss.Justification{ + SessionID: d.dealer.SessionID(), + Index: resp.Response.Index, // good index because of signature check + Deal: deal, + }, + } + return j, nil +} + +// ProcessJustification takes a justification and validates it. It returns an +// error in case the justification is wrong. +func (d *DistKeyGenerator) ProcessJustification(j *Justification) error { + v, ok := d.verifiers[j.Index] + if !ok { + return errors.New("dkg: Justification received but no deal for it") + } + return v.ProcessJustification(j.Justification) +} + +// SetTimeout triggers the timeout on all verifiers, and thus makes sure +// all verifiers have either responded, or have a StatusComplaint response. +func (d *DistKeyGenerator) SetTimeout() { + for _, v := range d.verifiers { + v.SetTimeout() + } +} + +// Certified returns true if all deals are certified. Normally, it *should* be +// only a threshold of deals but due to network synchronicity assumption, this +// is much easier. +func (d *DistKeyGenerator) Certified() bool { + if d.isResharing { + return len(d.QUAL()) >= len(d.c.OldNodes) + } + return len(d.QUAL()) >= len(d.c.NewNodes) +} + +// ExpectedDeals returns the number of deals that this node will +// receive from the other participants. +func (d *DistKeyGenerator) ExpectedDeals() int { + switch { + case d.newPresent && d.oldPresent: + return len(d.c.OldNodes) - 1 + case d.newPresent && !d.oldPresent: + return len(d.c.OldNodes) + default: + return 0 + } +} + +// QUAL returns the index in the list of participants that forms the QUALIFIED +// set as described in the "New-DKG" protocol by Rabin. Basically, it consists +// of all valid deals at the end of the protocols. It does NOT take into account +// any malicious share holder which share may have been revealed, due to invalid +// complaint. +// XXX Have a method of retrieving invalid shares ? +func (d *DistKeyGenerator) QUAL() []int { + var good []int + if d.isResharing && d.canIssue && !d.newPresent { + d.oldQualIter(func(i uint32, v *vss.Aggregator) bool { + good = append(good, int(i)) + return true + }) + return good + } + d.qualIter(func(i uint32, v *vss.Verifier) bool { + good = append(good, int(i)) + return true + }) + return good +} + +func (d *DistKeyGenerator) isInQUAL(idx uint32) bool { + var found bool + d.qualIter(func(i uint32, v *vss.Verifier) bool { + if i == idx { + found = true + return false + } + return true + }) + return found +} + +func (d *DistKeyGenerator) qualIter(fn func(idx uint32, v *vss.Verifier) bool) { + for i, v := range d.verifiers { + if v.DealCertified() { + if !fn(i, v) { + break + } + } + } +} + +func (d *DistKeyGenerator) oldQualIter(fn func(idx uint32, v *vss.Aggregator) bool) { + for i, v := range d.oldAggregators { + if v.DealCertified() { + if !fn(i, v) { + break + } + } + } +} + +// DistKeyShare generates the distributed key relative to this receiver. +// It throws an error if something is wrong such as not enough deals received. +// The shared secret can be computed when all deals have been sent and +// basically consists of a public point and a share. The public point is the sum +// of all aggregated individual public commits of each individual secrets. +// The share is evaluated from the global Private Polynomial, basically SUM of +// fj(i) for a receiver i. +func (d *DistKeyGenerator) DistKeyShare() (*DistKeyShare, error) { + if !d.Certified() { + return nil, errors.New("dkg: distributed key not certified") + } + if !d.canReceive { + return nil, errors.New("dkg: should not expect to compute any dist. share") + } + + if d.isResharing { + return d.resharingKey() + } + + return d.dkgKey() +} + +func (d *DistKeyGenerator) dkgKey() (*DistKeyShare, error) { + sh := d.suite.Scalar().Zero() + var pub *share.PubPoly + var err error + d.qualIter(func(i uint32, v *vss.Verifier) bool { + // share of dist. secret = sum of all share received. + deal := v.Deal() + s := deal.SecShare.V + sh = sh.Add(sh, s) + // Dist. public key = sum of all revealed commitments + poly := share.NewPubPoly(d.suite, d.suite.Point().Base(), deal.Commitments) + if pub == nil { + // first polynomial we see (instead of generating n empty commits) + pub = poly + return true + } + pub, err = pub.Add(poly) + return err == nil + }) + + if err != nil { + return nil, err + } + _, commits := pub.Info() + + return &DistKeyShare{ + Commits: commits, + Share: &share.PriShare{ + I: int(d.nidx), + V: sh, + }, + PrivatePoly: d.dealer.PrivatePoly().Coefficients(), + }, nil + +} + +func (d *DistKeyGenerator) resharingKey() (*DistKeyShare, error) { + // only old nodes sends shares + shares := make([]*share.PriShare, len(d.c.OldNodes)) + coeffs := make([][]kyber.Point, len(d.c.OldNodes)) + d.qualIter(func(i uint32, v *vss.Verifier) bool { + deal := v.Deal() + coeffs[int(i)] = deal.Commitments + // share of dist. secret. Invertion of rows/column + deal.SecShare.I = int(i) + shares[int(i)] = deal.SecShare + return true + }) + + // the private polynomial is generated from the old nodes, thus inheriting + // the old threshold condition + priPoly, err := share.RecoverPriPoly(d.suite, shares, d.oldT, len(d.c.NewNodes)) + if err != nil { + return nil, err + } + privateShare := &share.PriShare{ + I: int(d.nidx), + V: priPoly.Secret(), + } + + // recover public polynomial by interpolating coefficient-wise all + // polynomials + // the new public polynomial must however have "newT" coefficients since it + // will be held by the new nodes. + finalCoeffs := make([]kyber.Point, d.newT) + for i := 0; i < d.newT; i++ { + tmpCoeffs := make([]*share.PubShare, len(coeffs)) + // take all i-th coefficients + for j := range coeffs { + if coeffs[j] == nil { + continue + } + tmpCoeffs[j] = &share.PubShare{I: j, V: coeffs[j][i]} + } + + // using the old threshold / length because there are at most + // len(d.c.OldNodes) i-th coefficients since they are the one generating one + // each, thus using the old threshold. + coeff, err := share.RecoverCommit(d.suite, tmpCoeffs, d.oldT, len(d.c.OldNodes)) + if err != nil { + return nil, err + } + finalCoeffs[i] = coeff + } + + // Reconstruct the final public polynomial + pubPoly := share.NewPubPoly(d.suite, nil, finalCoeffs) + + if !pubPoly.Check(privateShare) { + return nil, errors.New("dkg: share do not correspond to public polynomial ><") + } + return &DistKeyShare{ + Commits: finalCoeffs, + Share: privateShare, + PrivatePoly: priPoly.Coefficients(), + }, nil +} + +// Verifiers returns the current mapping of indexes to verifiers. +func (d *DistKeyGenerator) Verifiers() map[uint32]*vss.Verifier { + return d.verifiers +} + +//Renew adds the new distributed key share g (with secret 0) to the distributed key share d. +func (d *DistKeyShare) Renew(suite Suite, g *DistKeyShare) (*DistKeyShare, error) { + //Check G(0) = 0*G. + if !g.Public().Equal(suite.Point().Base().Mul(suite.Scalar().Zero(), nil)) { + return nil, errors.New("wrong renewal function") + } + + //Check whether they have the same index + if d.Share.I != g.Share.I { + return nil, errors.New("not the same party") + } + + newShare := suite.Scalar().Add(d.Share.V, g.Share.V) + newCommits := make([]kyber.Point, len(d.Commits)) + for i := range newCommits { + newCommits[i] = suite.Point().Add(d.Commits[i], g.Commits[i]) + } + return &DistKeyShare{ + Commits: newCommits, + Share: &share.PriShare{ + I: d.Share.I, + V: newShare, + }, + }, nil +} + +func getPub(list []kyber.Point, i uint32) (kyber.Point, bool) { + if i >= uint32(len(list)) { + return nil, false + } + return list[i], true +} + +func findPub(list []kyber.Point, toFind kyber.Point) (int, bool) { + for i, p := range list { + if p.Equal(toFind) { + return i, true + } + } + return 0, false +} + +func checksDealCertified(i uint32, v *vss.Verifier) bool { + return v.DealCertified() +} diff --git a/kyber/share/dkg/pedersen/dkg_test.go b/kyber/share/dkg/pedersen/dkg_test.go new file mode 100644 index 0000000000..01dbe63b5f --- /dev/null +++ b/kyber/share/dkg/pedersen/dkg_test.go @@ -0,0 +1,788 @@ +package dkg + +import ( + "crypto/rand" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/share" + vss "go.dedis.ch/kyber/v3/share/vss/pedersen" +) + +var suite = edwards25519.NewBlakeSHA256Ed25519() + +const nbParticipants = 5 + +func generate() (partPubs []kyber.Point, partSec []kyber.Scalar, dkgs []*DistKeyGenerator) { + partPubs = make([]kyber.Point, nbParticipants) + partSec = make([]kyber.Scalar, nbParticipants) + for i := 0; i < nbParticipants; i++ { + sec, pub := genPair() + partPubs[i] = pub + partSec[i] = sec + } + dkgs = dkgGen(partPubs, partSec) + return +} + +func TestDKGNewDistKeyGenerator(t *testing.T) { + partPubs, partSec, _ := generate() + + long := partSec[0] + dkg, err := NewDistKeyGenerator(suite, long, partPubs, nbParticipants/2+1) + require.Nil(t, err) + require.NotNil(t, dkg.dealer) + require.True(t, dkg.canIssue) + require.True(t, dkg.canReceive) + require.True(t, dkg.newPresent) + // because we set old = new + require.True(t, dkg.oldPresent) + require.True(t, dkg.canReceive) + require.False(t, dkg.isResharing) + + sec, _ := genPair() + _, err = NewDistKeyGenerator(suite, sec, partPubs, nbParticipants/2+1) + require.Error(t, err) +} + +func TestDKGDeal(t *testing.T) { + _, _, dkgs := generate() + dkg := dkgs[0] + + dks, err := dkg.DistKeyShare() + require.Error(t, err) + require.Nil(t, dks) + + deals, err := dkg.Deals() + require.Nil(t, err) + require.Len(t, deals, nbParticipants-1) + + for i := range deals { + require.NotNil(t, deals[i]) + require.Equal(t, uint32(0), deals[i].Index) + } + + v, ok := dkg.verifiers[uint32(dkg.nidx)] + require.True(t, ok) + require.NotNil(t, v) +} + +func TestDKGProcessDeal(t *testing.T) { + _, _, dkgs := generate() + + dkg := dkgs[0] + deals, err := dkg.Deals() + require.Nil(t, err) + + rec := dkgs[1] + deal := deals[1] + require.Equal(t, int(deal.Index), 0) + require.Equal(t, 1, rec.nidx) + + // verifier don't find itself + goodP := rec.c.NewNodes + rec.c.NewNodes = make([]kyber.Point, 0) + resp, err := rec.ProcessDeal(deal) + require.Nil(t, resp) + require.Error(t, err) + rec.c.NewNodes = goodP + + // good deal + resp, err = rec.ProcessDeal(deal) + require.NotNil(t, resp) + require.Equal(t, vss.StatusApproval, resp.Response.Status) + require.Nil(t, err) + _, ok := rec.verifiers[deal.Index] + require.True(t, ok) + require.Equal(t, uint32(0), resp.Index) + + // duplicate + resp, err = rec.ProcessDeal(deal) + require.Nil(t, resp) + require.Error(t, err) + + // wrong index + goodIdx := deal.Index + deal.Index = uint32(nbParticipants + 1) + resp, err = rec.ProcessDeal(deal) + require.Nil(t, resp) + require.Error(t, err) + deal.Index = goodIdx + + // wrong deal + goodSig := deal.Deal.Signature + deal.Deal.Signature = randomBytes(len(deal.Deal.Signature)) + resp, err = rec.ProcessDeal(deal) + require.Nil(t, resp) + require.Error(t, err) + deal.Deal.Signature = goodSig + +} + +func TestDKGProcessResponse(t *testing.T) { + // first peer generates wrong deal + // second peer processes it and returns a complaint + // first peer process the complaint + + _, _, dkgs := generate() + dkg := dkgs[0] + idxRec := 1 + rec := dkgs[idxRec] + deal, err := dkg.dealer.PlaintextDeal(idxRec) + require.Nil(t, err) + + // give a wrong deal + goodSecret := deal.SecShare.V + deal.SecShare.V = suite.Scalar().Zero() + dd, err := dkg.Deals() + encD := dd[idxRec] + require.Nil(t, err) + resp, err := rec.ProcessDeal(encD) + require.Nil(t, err) + require.NotNil(t, resp) + require.Equal(t, vss.StatusComplaint, resp.Response.Status) + deal.SecShare.V = goodSecret + dd, _ = dkg.Deals() + encD = dd[idxRec] + + // no verifier tied to Response + v, ok := dkg.verifiers[0] + require.NotNil(t, v) + require.True(t, ok) + require.NotNil(t, v) + delete(dkg.verifiers, 0) + j, err := dkg.ProcessResponse(resp) + require.Nil(t, j) + require.NotNil(t, err) + dkg.verifiers[0] = v + + // invalid response + goodSig := resp.Response.Signature + resp.Response.Signature = randomBytes(len(goodSig)) + j, err = dkg.ProcessResponse(resp) + require.Nil(t, j) + require.Error(t, err) + resp.Response.Signature = goodSig + + // valid complaint from our deal + j, err = dkg.ProcessResponse(resp) + require.NotNil(t, j) + require.Nil(t, err) + + // valid complaint from another deal from another peer + dkg2 := dkgs[2] + require.Nil(t, err) + // fake a wrong deal + // deal20, err := dkg2.dealer.PlaintextDeal(0) + // require.Nil(t, err) + deal21, err := dkg2.dealer.PlaintextDeal(1) + require.Nil(t, err) + goodRnd21 := deal21.SecShare.V + deal21.SecShare.V = suite.Scalar().Zero() + deals2, err := dkg2.Deals() + require.Nil(t, err) + + resp12, err := rec.ProcessDeal(deals2[idxRec]) + require.NotNil(t, resp) + require.Equal(t, vss.StatusComplaint, resp12.Response.Status) + require.Equal(t, deals2[idxRec].Index, uint32(dkg2.nidx)) + require.Equal(t, resp12.Index, uint32(dkg2.nidx)) + require.Equal(t, vss.StatusComplaint, rec.verifiers[uint32(dkg2.oidx)].Responses()[uint32(rec.nidx)].Status) + + deal21.SecShare.V = goodRnd21 + deals2, err = dkg2.Deals() + require.Nil(t, err) + + // give it to the first peer + // process dealer 2's deal + r, err := dkg.ProcessDeal(deals2[0]) + require.Nil(t, err) + require.NotNil(t, r) + + // process response from peer 1 + j, err = dkg.ProcessResponse(resp12) + require.Nil(t, j) + require.Nil(t, err) + + // Justification part: + // give the complaint to the dealer + j, err = dkg2.ProcessResponse(resp12) + require.Nil(t, err) + require.NotNil(t, j) + + // hack because all is local, and resp has been modified locally by dkg2's + // dealer, the status has became "justified" + resp12.Response.Status = vss.StatusComplaint + err = dkg.ProcessJustification(j) + require.Nil(t, err) + + // remove verifiers + v = dkg.verifiers[j.Index] + delete(dkg.verifiers, j.Index) + err = dkg.ProcessJustification(j) + require.Error(t, err) + dkg.verifiers[j.Index] = v + +} + +func TestSetTimeout(t *testing.T) { + _, _, dkgs := generate() + + // full secret sharing exchange + // 1. broadcast deals + resps := make([]*Response, 0, nbParticipants*nbParticipants) + for _, dkg := range dkgs { + deals, err := dkg.Deals() + require.Nil(t, err) + for i, d := range deals { + resp, err := dkgs[i].ProcessDeal(d) + require.Nil(t, err) + require.Equal(t, vss.StatusApproval, resp.Response.Status) + resps = append(resps, resp) + } + } + + // 2. Broadcast responses + for _, resp := range resps { + for _, dkg := range dkgs { + if !dkg.verifiers[resp.Index].EnoughApprovals() { + // ignore messages about ourself + if resp.Response.Index == uint32(dkg.nidx) { + continue + } + j, err := dkg.ProcessResponse(resp) + require.Nil(t, err) + require.Nil(t, j) + } + } + } + + // 3. make sure everyone has the same QUAL set + for _, dkg := range dkgs { + for _, dkg2 := range dkgs { + require.False(t, dkg.isInQUAL(uint32(dkg2.nidx))) + } + } + + for _, dkg := range dkgs { + dkg.SetTimeout() + } + + for _, dkg := range dkgs { + for _, dkg2 := range dkgs { + require.True(t, dkg.isInQUAL(uint32(dkg2.nidx))) + } + } + +} + +func TestDistKeyShare(t *testing.T) { + _, _, dkgs := generate() + fullExchange(t, dkgs) + + for _, dkg := range dkgs { + require.True(t, dkg.Certified()) + } + // verify integrity of shares etc + dkss := make([]*DistKeyShare, nbParticipants) + var poly *share.PriPoly + for i, dkg := range dkgs { + dks, err := dkg.DistKeyShare() + require.Nil(t, err) + require.NotNil(t, dks) + require.NotNil(t, dks.PrivatePoly) + dkss[i] = dks + require.Equal(t, dkg.nidx, dks.Share.I) + + pripoly := share.CoefficientsToPriPoly(suite, dks.PrivatePoly) + if poly == nil { + poly = pripoly + continue + } + poly, err = poly.Add(pripoly) + require.NoError(t, err) + } + + shares := make([]*share.PriShare, nbParticipants) + for i, dks := range dkss { + require.True(t, checkDks(dks, dkss[0]), "dist key share not equal %d vs %d", dks.Share.I, 0) + shares[i] = dks.Share + } + + secret, err := share.RecoverSecret(suite, shares, nbParticipants, nbParticipants) + require.Nil(t, err) + + secretCoeffs := poly.Coefficients() + require.Equal(t, secret.String(), secretCoeffs[0].String()) + + commitSecret := suite.Point().Mul(secret, nil) + require.Equal(t, dkss[0].Public().String(), commitSecret.String()) +} + +func dkgGen(partPubs []kyber.Point, partSec []kyber.Scalar) []*DistKeyGenerator { + dkgs := make([]*DistKeyGenerator, nbParticipants) + for i := 0; i < nbParticipants; i++ { + dkg, err := NewDistKeyGenerator(suite, partSec[i], partPubs, vss.MinimumT(nbParticipants)) + if err != nil { + panic(err) + } + dkgs[i] = dkg + } + return dkgs +} + +func genPair() (kyber.Scalar, kyber.Point) { + sc := suite.Scalar().Pick(suite.RandomStream()) + return sc, suite.Point().Mul(sc, nil) +} + +func randomBytes(n int) []byte { + var buff = make([]byte, n) + _, _ = rand.Read(buff[:]) + return buff +} +func checkDks(dks1, dks2 *DistKeyShare) bool { + if len(dks1.Commits) != len(dks2.Commits) { + return false + } + for i, p := range dks1.Commits { + if !p.Equal(dks2.Commits[i]) { + return false + } + } + return true +} + +func fullExchange(t *testing.T, dkgs []*DistKeyGenerator) { + // full secret sharing exchange + // 1. broadcast deals + resps := make([]*Response, 0, nbParticipants*nbParticipants) + for idx, dkg := range dkgs { + deals, err := dkg.Deals() + require.Nil(t, err) + for i, d := range deals { + require.True(t, i != idx) + resp, err := dkgs[i].ProcessDeal(d) + require.Nil(t, err) + require.Equal(t, vss.StatusApproval, resp.Response.Status) + resps = append(resps, resp) + } + } + // 2. Broadcast responses + for _, resp := range resps { + for _, dkg := range dkgs { + // Ignore messages about ourselves + if resp.Response.Index == uint32(dkg.nidx) { + continue + } + j, err := dkg.ProcessResponse(resp) + require.Nil(t, err) + require.Nil(t, j) + } + } + + // 3. make sure everyone has the same QUAL set + for _, dkg := range dkgs { + for _, dkg2 := range dkgs { + require.True(t, dkg.isInQUAL(uint32(dkg2.nidx))) + } + } +} + +// Test resharing of a DKG to the same set of nodes +func TestDKGResharing(t *testing.T) { + partPubs, partSec, dkgs := generate() + fullExchange(t, dkgs) + + shares := make([]*DistKeyShare, len(dkgs)) + sshares := make([]*share.PriShare, len(dkgs)) + for i, dkg := range dkgs { + share, err := dkg.DistKeyShare() + require.NoError(t, err) + shares[i] = share + sshares[i] = shares[i].Share + } + // start resharing within the same group + newDkgs := make([]*DistKeyGenerator, len(dkgs)) + var err error + for i := range dkgs { + c := &Config{ + Suite: suite, + Longterm: partSec[i], + OldNodes: partPubs, + NewNodes: partPubs, + Share: shares[i], + } + newDkgs[i], err = NewDistKeyHandler(c) + require.NoError(t, err) + } + fullExchange(t, newDkgs) + newShares := make([]*DistKeyShare, len(dkgs)) + newSShares := make([]*share.PriShare, len(dkgs)) + for i := range newDkgs { + dks, err := newDkgs[i].DistKeyShare() + require.NoError(t, err) + newShares[i] = dks + newSShares[i] = newShares[i].Share + } + // check + // 1. shares are different between the two rounds + // 2. shares reconstruct to the same secret + // 3. public polynomial is different but for the first coefficient /public + // key/ + // 1. + for i := 0; i < len(dkgs); i++ { + require.False(t, shares[i].Share.V.Equal(newShares[i].Share.V)) + } + thr := vss.MinimumT(nbParticipants) + // 2. + oldSecret, err := share.RecoverSecret(suite, sshares, thr, nbParticipants) + require.NoError(t, err) + newSecret, err := share.RecoverSecret(suite, newSShares, thr, nbParticipants) + require.NoError(t, err) + require.Equal(t, oldSecret.String(), newSecret.String()) +} + +// Test resharing to a different set of nodes with one common +func TestDKGResharingNewNodes(t *testing.T) { + partPubs, partSec, dkgs := generate() + fullExchange(t, dkgs) + + shares := make([]*DistKeyShare, len(dkgs)) + sshares := make([]*share.PriShare, len(dkgs)) + for i, dkg := range dkgs { + share, err := dkg.DistKeyShare() + require.NoError(t, err) + shares[i] = share + sshares[i] = shares[i].Share + } + // start resharing to a different group + oldN := nbParticipants + oldT := len(shares[0].Commits) + newN := oldN + 1 + newT := oldT + 1 + privates := make([]kyber.Scalar, newN) + publics := make([]kyber.Point, newN) + privates[0] = dkgs[oldN-1].long + publics[0] = suite.Point().Mul(privates[0], nil) + for i := 1; i < newN; i++ { + privates[i] = suite.Scalar().Pick(suite.RandomStream()) + publics[i] = suite.Point().Mul(privates[i], nil) + } + + // creating the old dkgs and new dkgs + oldDkgs := make([]*DistKeyGenerator, oldN) + newDkgs := make([]*DistKeyGenerator, newN) + var err error + for i := 0; i < oldN; i++ { + c := &Config{ + Suite: suite, + Longterm: partSec[i], + OldNodes: partPubs, + NewNodes: publics, + Share: shares[i], + Threshold: newT, + } + oldDkgs[i], err = NewDistKeyHandler(c) + require.NoError(t, err) + if i == oldN-1 { + require.True(t, oldDkgs[i].canReceive) + require.True(t, oldDkgs[i].canIssue) + require.True(t, oldDkgs[i].isResharing) + require.True(t, oldDkgs[i].newPresent) + require.Equal(t, oldDkgs[i].oidx, i) + require.Equal(t, 0, oldDkgs[i].nidx) + continue + } + require.False(t, oldDkgs[i].canReceive) + require.True(t, oldDkgs[i].canIssue) + require.True(t, oldDkgs[i].isResharing) + require.False(t, oldDkgs[i].newPresent) + require.Equal(t, oldDkgs[i].oidx, i) + } + // the first one is the last old one + newDkgs[0] = oldDkgs[oldN-1] + for i := 1; i < newN; i++ { + c := &Config{ + Suite: suite, + Longterm: privates[i], + OldNodes: partPubs, + NewNodes: publics, + PublicCoeffs: shares[0].Commits, + Threshold: newT, + } + newDkgs[i], err = NewDistKeyHandler(c) + require.NoError(t, err) + require.True(t, newDkgs[i].canReceive) + require.False(t, newDkgs[i].canIssue) + require.True(t, newDkgs[i].isResharing) + require.True(t, newDkgs[i].newPresent) + require.Equal(t, newDkgs[i].nidx, i) + } + + // full secret sharing exchange + // 1. broadcast deals + deals := make([]map[int]*Deal, 0, newN*newN) + for _, dkg := range oldDkgs { + localDeals, err := dkg.Deals() + require.Nil(t, err) + deals = append(deals, localDeals) + if dkg.canReceive && dkg.nidx == 0 { + // because it stores its own deal / response + require.Equal(t, 1, len(dkg.verifiers)) + } else { + require.Equal(t, 0, len(dkg.verifiers)) + } + } + + // the index key indicates the dealer index for which the responses are for + resps := make(map[int][]*Response) + for i, localDeals := range deals { + for j, d := range localDeals { + dkg := newDkgs[j] + resp, err := dkg.ProcessDeal(d) + require.Nil(t, err) + require.Equal(t, vss.StatusApproval, resp.Response.Status) + resps[i] = append(resps[i], resp) + } + } + + // all new dkgs should have the same length of verifiers map + for _, dkg := range newDkgs { + // one deal per old participants + require.Equal(t, oldN, len(dkg.verifiers), "dkg nidx %d failing", dkg.nidx) + } + + // 2. Broadcast responses + for _, dealResponses := range resps { + for _, resp := range dealResponses { + for _, dkg := range oldDkgs { + // Ignore messages from ourselves + if resp.Response.Index == uint32(dkg.nidx) { + continue + } + j, err := dkg.ProcessResponse(resp) + //fmt.Printf("old dkg %d process responses from new dkg %d about deal %d\n", dkg.oidx, dkg.nidx, resp.Index) + if err != nil { + fmt.Printf("old dkg at (oidx %d, nidx %d) has received response from idx %d for dealer idx %d\n", dkg.oidx, dkg.nidx, resp.Response.Index, resp.Index) + } + require.Nil(t, err) + require.Nil(t, j) + } + + for _, dkg := range newDkgs[1:] { + // Ignore messages from ourselves + if resp.Response.Index == uint32(dkg.nidx) { + continue + } + j, err := dkg.ProcessResponse(resp) + //fmt.Printf("new dkg %d process responses from new dkg %d about deal %d\n", dkg.nidx, dkg.nidx, resp.Index) + if err != nil { + fmt.Printf("new dkg at nidx %d has received response from idx %d for deal %d\n", dkg.nidx, resp.Response.Index, resp.Index) + } + require.Nil(t, err) + require.Nil(t, j) + } + + } + } + + for _, dkg := range newDkgs { + for i := 0; i < oldN; i++ { + require.True(t, dkg.verifiers[uint32(i)].DealCertified(), "new dkg %d has not certified deal %d => %v", dkg.nidx, i, dkg.verifiers[uint32(i)].Responses()) + } + } + + // 3. make sure everyone has the same QUAL set + for _, dkg := range newDkgs { + for _, dkg2 := range oldDkgs { + require.True(t, dkg.isInQUAL(uint32(dkg2.oidx)), "new dkg %d has not in qual old dkg %d (qual = %v)", dkg.nidx, dkg2.oidx, dkg.QUAL()) + } + } + + newShares := make([]*DistKeyShare, newN) + newSShares := make([]*share.PriShare, newN) + for i := range newDkgs { + dks, err := newDkgs[i].DistKeyShare() + require.NoError(t, err) + newShares[i] = dks + newSShares[i] = newShares[i].Share + } + // check shares reconstruct to the same secret + oldSecret, err := share.RecoverSecret(suite, sshares, oldT, oldN) + require.NoError(t, err) + newSecret, err := share.RecoverSecret(suite, newSShares, newT, newN) + require.NoError(t, err) + require.Equal(t, oldSecret.String(), newSecret.String()) +} + +func TestDKGResharingPartialNewNodes(t *testing.T) { + partPubs, partSec, dkgs := generate() + fullExchange(t, dkgs) + + shares := make([]*DistKeyShare, len(dkgs)) + sshares := make([]*share.PriShare, len(dkgs)) + for i, dkg := range dkgs { + share, err := dkg.DistKeyShare() + require.NoError(t, err) + shares[i] = share + sshares[i] = shares[i].Share + } + // start resharing to a different group + oldN := nbParticipants + oldT := len(shares[0].Commits) + newN := oldN + 1 + newT := oldT + 1 + total := oldN + 2 + newOffset := oldN - 1 // idx at which a new key is added to the group + + privates := make([]kyber.Scalar, 0, newN) + publics := make([]kyber.Point, 0, newN) + for _, dkg := range dkgs[1:] { + privates = append(privates, dkg.long) + publics = append(publics, suite.Point().Mul(privates[len(privates)-1], nil)) + } + // add two new guys + privates = append(privates, suite.Scalar().Pick(suite.RandomStream())) + publics = append(publics, suite.Point().Mul(privates[len(privates)-1], nil)) + privates = append(privates, suite.Scalar().Pick(suite.RandomStream())) + publics = append(publics, suite.Point().Mul(privates[len(privates)-1], nil)) + + // creating all dkgs + totalDkgs := make([]*DistKeyGenerator, total) + var err error + for i := 0; i < oldN; i++ { + c := &Config{ + Suite: suite, + Longterm: partSec[i], + OldNodes: partPubs, + NewNodes: publics, + Share: shares[i], + Threshold: newT, + } + totalDkgs[i], err = NewDistKeyHandler(c) + require.NoError(t, err) + if i >= 1 { + require.True(t, totalDkgs[i].canReceive) + require.True(t, totalDkgs[i].canIssue) + require.True(t, totalDkgs[i].isResharing) + require.True(t, totalDkgs[i].newPresent) + require.Equal(t, totalDkgs[i].oidx, i) + require.Equal(t, i-1, totalDkgs[i].nidx) + continue + } + require.False(t, totalDkgs[i].canReceive) + require.True(t, totalDkgs[i].canIssue) + require.True(t, totalDkgs[i].isResharing) + require.False(t, totalDkgs[i].newPresent) + require.Equal(t, totalDkgs[i].oidx, i) + } + // the first one is the last old one + for i := oldN; i < total; i++ { + newIdx := i - oldN + newOffset + c := &Config{ + Suite: suite, + Longterm: privates[newIdx], + OldNodes: partPubs, + NewNodes: publics, + PublicCoeffs: shares[0].Commits, + Threshold: newT, + } + totalDkgs[i], err = NewDistKeyHandler(c) + require.NoError(t, err) + require.True(t, totalDkgs[i].canReceive) + require.False(t, totalDkgs[i].canIssue) + require.True(t, totalDkgs[i].isResharing) + require.True(t, totalDkgs[i].newPresent) + require.Equal(t, totalDkgs[i].nidx, newIdx) + } + newDkgs := totalDkgs[1:] + oldDkgs := totalDkgs[:oldN] + require.Equal(t, oldN, len(oldDkgs)) + require.Equal(t, newN, len(newDkgs)) + + // full secret sharing exchange + // 1. broadcast deals + deals := make([]map[int]*Deal, 0, newN*newN) + for _, dkg := range oldDkgs { + localDeals, err := dkg.Deals() + require.Nil(t, err) + deals = append(deals, localDeals) + if dkg.canReceive && dkg.newPresent { + // because it stores its own deal / response + require.Equal(t, 1, len(dkg.verifiers)) + } else { + require.Equal(t, 0, len(dkg.verifiers)) + } + } + + // the index key indicates the dealer index for which the responses are for + resps := make(map[int][]*Response) + for i, localDeals := range deals { + for j, d := range localDeals { + dkg := newDkgs[j] + resp, err := dkg.ProcessDeal(d) + require.Nil(t, err) + require.Equal(t, vss.StatusApproval, resp.Response.Status) + resps[i] = append(resps[i], resp) + if i == 0 { + //fmt.Printf("dealer (oidx %d, nidx %d) processing deal to %d from %d\n", newDkgs[i].oidx, newDkgs[i].nidx, i, d.Index) + } + } + } + + // all new dkgs should have the same length of verifiers map + for _, dkg := range newDkgs { + // one deal per old participants + require.Equal(t, oldN, len(dkg.verifiers), "dkg nidx %d failing", dkg.nidx) + } + + // 2. Broadcast responses + for _, dealResponses := range resps { + for _, resp := range dealResponses { + for _, dkg := range totalDkgs { + // Ignore messages from ourselves + if dkg.canReceive && resp.Response.Index == uint32(dkg.nidx) { + continue + } + j, err := dkg.ProcessResponse(resp) + //fmt.Printf("old dkg %d process responses from new dkg %d about deal %d\n", dkg.oidx, dkg.nidx, resp.Index) + if err != nil { + fmt.Printf("old dkg at (oidx %d, nidx %d) has received response from idx %d for dealer idx %d\n", dkg.oidx, dkg.nidx, resp.Response.Index, resp.Index) + } + require.Nil(t, err) + require.Nil(t, j) + } + } + } + for _, dkg := range newDkgs { + for i := 0; i < oldN; i++ { + require.True(t, dkg.verifiers[uint32(i)].DealCertified(), "new dkg %d has not certified deal %d => %v", dkg.nidx, i, dkg.verifiers[uint32(i)].Responses()) + } + } + + // 3. make sure everyone has the same QUAL set + for _, dkg := range newDkgs { + for _, dkg2 := range oldDkgs { + require.True(t, dkg.isInQUAL(uint32(dkg2.oidx)), "new dkg %d has not in qual old dkg %d (qual = %v)", dkg.nidx, dkg2.oidx, dkg.QUAL()) + } + } + + newShares := make([]*DistKeyShare, newN) + newSShares := make([]*share.PriShare, newN) + for i := range newDkgs { + dks, err := newDkgs[i].DistKeyShare() + require.NoError(t, err) + newShares[i] = dks + newSShares[i] = newShares[i].Share + } + // check shares reconstruct to the same secret + oldSecret, err := share.RecoverSecret(suite, sshares, oldT, oldN) + require.NoError(t, err) + newSecret, err := share.RecoverSecret(suite, newSShares, newT, newN) + require.NoError(t, err) + require.Equal(t, oldSecret.String(), newSecret.String()) +} diff --git a/kyber/share/dkg/pedersen/structs.go b/kyber/share/dkg/pedersen/structs.go new file mode 100644 index 0000000000..6ffab89afe --- /dev/null +++ b/kyber/share/dkg/pedersen/structs.go @@ -0,0 +1,77 @@ +package dkg + +import ( + "bytes" + "encoding/binary" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/share" + vss "go.dedis.ch/kyber/v3/share/vss/pedersen" +) + +// DistKeyShare holds the share of a distributed key for a participant. +type DistKeyShare struct { + // Coefficients of the public polynomial holding the public key. + Commits []kyber.Point + // Share of the distributed secret which is private information. + Share *share.PriShare + // Coefficients of the private polynomial generated by the node holding the + // share. The final distributed polynomial is the sum of all these + // individual polynomials, but it is never computed. + PrivatePoly []kyber.Scalar +} + +// Public returns the public key associated with the distributed private key. +func (d *DistKeyShare) Public() kyber.Point { + return d.Commits[0] +} + +// PriShare implements the dss.DistKeyShare interface so either pedersen or +// rabin dkg can be used with dss. +func (d *DistKeyShare) PriShare() *share.PriShare { + return d.Share +} + +// Commitments implements the dss.DistKeyShare interface so either pedersen or +// rabin dkg can be used with dss. +func (d *DistKeyShare) Commitments() []kyber.Point { + return d.Commits +} + +// Deal holds the Deal for one participant as well as the index of the issuing +// Dealer. +type Deal struct { + // Index of the Dealer in the list of participants + Index uint32 + // Deal issued for another participant + Deal *vss.EncryptedDeal + // Signature over the whole message + Signature []byte +} + +// MarshalBinary returns a binary representation of this deal, which is the +// message signed in a dkg deal. +func (d *Deal) MarshalBinary() ([]byte, error) { + var b bytes.Buffer + binary.Write(&b, binary.LittleEndian, d.Index) + b.Write(d.Deal.Cipher) + return b.Bytes(), nil +} + +// Response holds the Response from another participant as well as the index of +// the target Dealer. +type Response struct { + // Index of the Dealer for which this response is for + Index uint32 + // Response issued from another participant + Response *vss.Response +} + +// Justification holds the Justification from a Dealer as well as the index of +// the Dealer in question. +type Justification struct { + // Index of the Dealer who answered with this Justification + Index uint32 + // Justification issued from the Dealer + Justification *vss.Justification +} diff --git a/kyber/share/dkg/rabin/dkg.go b/kyber/share/dkg/rabin/dkg.go new file mode 100644 index 0000000000..376d1e1a41 --- /dev/null +++ b/kyber/share/dkg/rabin/dkg.go @@ -0,0 +1,695 @@ +// Package dkg implements the protocol described in +// "Secure Distributed Key Generation for Discrete-Log +// Based Cryptosystems" by R. Gennaro, S. Jarecki, H. Krawczyk, and T. Rabin. +// DKG enables a group of participants to generate a distributed key +// with each participants holding only a share of the key. The key is also +// never computed locally but generated distributively whereas the public part +// of the key is known by every participants. +// The underlying basis for this protocol is the VSS protocol implemented in the +// share/vss package. +// +// The protocol works as follow: +// +// 1. Each participant instantiates a DistKeyShare (DKS) struct. +// 2. Then each participant runs an instance of the VSS protocol: +// - each participant generates their deals with the method `Deals()` and then +// sends them to the right recipient. +// - each participant processes the received deal with `ProcessDeal()` and +// broadcasts the resulting response. +// - each participant processes the response with `ProcessResponse()`. If a +// justification is returned, it must be broadcasted. +// 3. Each participant can check if step 2. is done by calling +// `Certified()`.Those participants where Certified() returned true, belong to +// the set of "qualified" participants who will generate the distributed +// secret. To get the list of qualified participants, use QUAL(). +// 4. Each QUAL participant generates their secret commitments calling +// `SecretCommits()` and broadcasts them to the QUAL set. +// 5. Each QUAL participant processes the received secret commitments using +// `SecretCommits()`. If there is an error, it can return a commitment complaint +// (ComplaintCommits) that must be broadcasted to the QUAL set. +// 6. Each QUAL participant receiving a complaint can process it with +// `ProcessComplaintCommits()` which returns the secret share +// (ReconstructCommits) given from the malicious participant. This structure +// must be broadcasted to all the QUAL participant. +// 7. At this point, every QUAL participant can issue the distributed key by +// calling `DistKeyShare()`. +package dkg + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/sign/schnorr" + "go.dedis.ch/protobuf" + + "go.dedis.ch/kyber/v3/share" + vss "go.dedis.ch/kyber/v3/share/vss/rabin" +) + +// Suite wraps the functionalities needed by the dkg package +type Suite vss.Suite + +// DistKeyShare holds the share of a distributed key for a participant. +type DistKeyShare struct { + // Coefficients of the public polynomial holding the public key + Commits []kyber.Point + // Share of the distributed secret + Share *share.PriShare +} + +// Public returns the public key associated with the distributed private key. +func (d *DistKeyShare) Public() kyber.Point { + return d.Commits[0] +} + +// PriShare implements the dss.DistKeyShare interface so either pedersen or +// rabin dkg can be used with dss. +func (d *DistKeyShare) PriShare() *share.PriShare { + return d.Share +} + +// Commitments implements the dss.DistKeyShare interface so either pedersen or +// rabin dkg can be used with dss. +func (d *DistKeyShare) Commitments() []kyber.Point { + return d.Commits +} + +// Deal holds the Deal for one participant as well as the index of the issuing +// Dealer. +// NOTE: Doing that in vss.go would be possible but then the Dealer is always +// assumed to be a member of the participants. It's only the case here. +type Deal struct { + // Index of the Dealer in the list of participants + Index uint32 + // Deal issued for another participant + Deal *vss.EncryptedDeal +} + +// Response holds the Response from another participant as well as the index of +// the target Dealer. +type Response struct { + // Index of the Dealer for which this response is for + Index uint32 + // Response issued from another participant + Response *vss.Response +} + +// Justification holds the Justification from a Dealer as well as the index of +// the Dealer in question. +type Justification struct { + // Index of the Dealer who answered with this Justification + Index uint32 + // Justification issued from the Dealer + Justification *vss.Justification +} + +// SecretCommits is sent during the distributed public key reconstruction phase, +// basically a Feldman VSS scheme. +type SecretCommits struct { + // Index of the Dealer in the list of participants + Index uint32 + // Commitments generated by the Dealer + Commitments []kyber.Point + // SessionID generated by the Dealer tied to the Deal + SessionID []byte + // Signature from the Dealer + Signature []byte +} + +// ComplaintCommits is sent if the secret commitments revealed by a peer are not +// valid. +type ComplaintCommits struct { + // Index of the Verifier _issuing_ the ComplaintCommit + Index uint32 + // DealerIndex being the index of the Dealer who issued the SecretCommits + DealerIndex uint32 + // Deal that has been given from the Dealer (at DealerIndex) to this node + // (at Index) + Deal *vss.Deal + // Signature made by the verifier + Signature []byte +} + +// ReconstructCommits holds the information given by a participant who reveals +// the deal received from a peer that has received a ComplaintCommits. +type ReconstructCommits struct { + // Id of the session + SessionID []byte + // Index of the verifier who received the deal + Index uint32 + // DealerIndex is the index of the dealer who issued the Deal + DealerIndex uint32 + // Share contained in the Deal + Share *share.PriShare + // Signature over all over fields generated by the issuing verifier + Signature []byte +} + +// DistKeyGenerator is the struct that runs the DKG protocol. +type DistKeyGenerator struct { + suite Suite + + index uint32 + long kyber.Scalar + pub kyber.Point + + participants []kyber.Point + + t int + + dealer *vss.Dealer + verifiers map[uint32]*vss.Verifier + + // list of commitments to each secret polynomial + commitments map[uint32]*share.PubPoly + + // Map of deals collected to reconstruct the full polynomial of a dealer. + // The key is index of the dealer. Once there are enough ReconstructCommits + // struct, this dkg will re-construct the polynomial and stores it into the + // list of commitments. + pendingReconstruct map[uint32][]*ReconstructCommits + reconstructed map[uint32]bool +} + +// NewDistKeyGenerator returns a DistKeyGenerator out of the suite, +// the longterm secret key, the list of participants, and the +// threshold t parameter. It returns an error if the secret key's +// commitment can't be found in the list of participants. +func NewDistKeyGenerator(suite Suite, longterm kyber.Scalar, participants []kyber.Point, t int) (*DistKeyGenerator, error) { + pub := suite.Point().Mul(longterm, nil) + // find our index + var found bool + var index uint32 + for i, p := range participants { + if p.Equal(pub) { + found = true + index = uint32(i) + break + } + } + if !found { + return nil, errors.New("dkg: own public key not found in list of participants") + } + var err error + // generate our dealer / deal + ownSec := suite.Scalar().Pick(suite.RandomStream()) + dealer, err := vss.NewDealer(suite, longterm, ownSec, participants, t) + if err != nil { + return nil, err + } + + return &DistKeyGenerator{ + dealer: dealer, + verifiers: make(map[uint32]*vss.Verifier), + commitments: make(map[uint32]*share.PubPoly), + pendingReconstruct: make(map[uint32][]*ReconstructCommits), + reconstructed: make(map[uint32]bool), + t: t, + suite: suite, + long: longterm, + pub: pub, + participants: participants, + index: index, + }, nil +} + +// Deals returns all the deals that must be broadcasted to all +// participants. The deal corresponding to this DKG is already added +// to this DKG and is ommitted from the returned map. To know +// to which participant a deal belongs to, loop over the keys as indices in +// the list of participants: +// +// for i,dd := range distDeals { +// sendTo(participants[i],dd) +// } +// +// This method panics if it can't process its own deal. +func (d *DistKeyGenerator) Deals() (map[int]*Deal, error) { + deals, err := d.dealer.EncryptedDeals() + if err != nil { + return nil, err + } + dd := make(map[int]*Deal) + for i := range d.participants { + distd := &Deal{ + Index: d.index, + Deal: deals[i], + } + if i == int(d.index) { + if _, ok := d.verifiers[d.index]; ok { + // already processed our own deal + continue + } + + resp, err := d.ProcessDeal(distd) + if err != nil { + panic(err) + } else if !resp.Response.Approved { + panic("dkg: own deal gave a complaint") + } + + // If processed own deal correctly, set positive response in this + // DKG's dealer's own verifier + d.dealer.UnsafeSetResponseDKG(d.index, true) + continue + } + dd[i] = distd + } + return dd, nil +} + +// ProcessDeal takes a Deal created by Deals() and stores and verifies it. It +// returns a Response to broadcast to every other participants. It returns an +// error in case the deal has already been stored, or if the deal is incorrect +// (see `vss.Verifier.ProcessEncryptedDeal()`). +func (d *DistKeyGenerator) ProcessDeal(dd *Deal) (*Response, error) { + // public key of the dealer + pub, ok := findPub(d.participants, dd.Index) + if !ok { + return nil, errors.New("dkg: dist deal out of bounds index") + } + + if _, ok := d.verifiers[dd.Index]; ok { + return nil, errors.New("dkg: already received dist deal from same index") + } + + // verifier receiving the dealer's deal + ver, err := vss.NewVerifier(d.suite, d.long, pub, d.participants) + if err != nil { + return nil, err + } + + d.verifiers[dd.Index] = ver + resp, err := ver.ProcessEncryptedDeal(dd.Deal) + if err != nil { + return nil, err + } + + // Set StatusApproval for the verifier that represents the participant + // that distibuted the Deal + d.verifiers[dd.Index].UnsafeSetResponseDKG(dd.Index, true) + + return &Response{ + Index: dd.Index, + Response: resp, + }, nil +} + +// ProcessResponse takes a response from every other peer. If the response +// designates the deal of another participants than this dkg, this dkg stores it +// and returns nil with a possible error regarding the validity of the response. +// If the response designates a deal this dkg has issued, then the dkg will process +// the response, and returns a justification. +func (d *DistKeyGenerator) ProcessResponse(resp *Response) (*Justification, error) { + v, ok := d.verifiers[resp.Index] + if !ok { + return nil, errors.New("dkg: complaint received but no deal for it") + } + + if err := v.ProcessResponse(resp.Response); err != nil { + return nil, err + } + + if resp.Index != uint32(d.index) { + return nil, nil + } + + j, err := d.dealer.ProcessResponse(resp.Response) + if err != nil { + return nil, err + } + if j == nil { + return nil, nil + } + // a justification for our own deal, are we cheating !? + if err := v.ProcessJustification(j); err != nil { + return nil, err + } + + return &Justification{ + Index: d.index, + Justification: j, + }, nil +} + +// ProcessJustification takes a justification and validates it. It returns an +// error in case the justification is wrong. +func (d *DistKeyGenerator) ProcessJustification(j *Justification) error { + v, ok := d.verifiers[j.Index] + if !ok { + return errors.New("dkg: Justification received but no deal for it") + } + return v.ProcessJustification(j.Justification) +} + +// SetTimeout triggers the timeout on all verifiers, and thus makes sure +// all verifiers have either responded, or have a StatusComplaint response. +func (d *DistKeyGenerator) SetTimeout() { + for _, v := range d.verifiers { + v.SetTimeout() + } +} + +// Certified returns true if at least t deals are certified (see +// vss.Verifier.DealCertified()). If the distribution is certified, the protocol +// can continue using d.SecretCommits(). +func (d *DistKeyGenerator) Certified() bool { + return len(d.QUAL()) >= d.t +} + +// QUAL returns the index in the list of participants that forms the QUALIFIED +// set as described in the "New-DKG" protocol by Rabin. Basically, it consists +// of all participants that are not disqualified after having exchanged all +// deals, responses and justification. This is the set that is used to extract +// the distributed public key with SecretCommits() and ProcessSecretCommits(). +func (d *DistKeyGenerator) QUAL() []int { + var good []int + d.qualIter(func(i uint32, v *vss.Verifier) bool { + good = append(good, int(i)) + return true + }) + return good +} + +func (d *DistKeyGenerator) isInQUAL(idx uint32) bool { + var found bool + d.qualIter(func(i uint32, v *vss.Verifier) bool { + if i == idx { + found = true + return false + } + return true + }) + return found +} + +func (d *DistKeyGenerator) qualIter(fn func(idx uint32, v *vss.Verifier) bool) { + for i, v := range d.verifiers { + if v.DealCertified() { + if !fn(i, v) { + break + } + } + } +} + +// SecretCommits returns the commitments of the coefficients of the secret +// polynomials. This secret commits must be broadcasted to every other +// participant and must be processed by ProcessSecretCommits. In this manner, +// the coefficients are revealed through a Feldman VSS scheme. +// This dkg must have its deal certified, otherwise it returns an error. The +// SecretCommits returned is already added to this dkg's list of SecretCommits. +func (d *DistKeyGenerator) SecretCommits() (*SecretCommits, error) { + if !d.dealer.DealCertified() { + return nil, errors.New("dkg: can't give SecretCommits if deal not certified") + } + sc := &SecretCommits{ + Commitments: d.dealer.Commits(), + Index: uint32(d.index), + SessionID: d.dealer.SessionID(), + } + msg := sc.Hash(d.suite) + sig, err := schnorr.Sign(d.suite, d.long, msg) + if err != nil { + return nil, err + } + sc.Signature = sig + // adding our own commitments + d.commitments[uint32(d.index)] = share.NewPubPoly(d.suite, d.suite.Point().Base(), sc.Commitments) + return sc, err +} + +// ProcessSecretCommits takes a SecretCommits from every other participant and +// verifies and stores it. It returns an error in case the SecretCommits is +// invalid. In case the SecretCommits are valid, but this dkg can't verify its +// share, it returns a ComplaintCommits that must be broadcasted to every other +// participant. It returns (nil,nil) otherwise. +func (d *DistKeyGenerator) ProcessSecretCommits(sc *SecretCommits) (*ComplaintCommits, error) { + pub, ok := findPub(d.participants, sc.Index) + if !ok { + return nil, errors.New("dkg: secretcommits received with index out of bounds") + } + + if !d.isInQUAL(sc.Index) { + return nil, errors.New("dkg: secretcommits from a non QUAL member") + } + + // mapping verified by isInQUAL + v := d.verifiers[sc.Index] + + if !bytes.Equal(v.SessionID(), sc.SessionID) { + return nil, errors.New("dkg: secretcommits received with wrong session id") + } + + msg := sc.Hash(d.suite) + if err := schnorr.Verify(d.suite, pub, msg, sc.Signature); err != nil { + return nil, err + } + + deal := v.Deal() + poly := share.NewPubPoly(d.suite, d.suite.Point().Base(), sc.Commitments) + if !poly.Check(deal.SecShare) { + cc := &ComplaintCommits{ + Index: uint32(d.index), + DealerIndex: sc.Index, + Deal: deal, + } + var err error + msg := cc.Hash(d.suite) + if cc.Signature, err = schnorr.Sign(d.suite, d.long, msg); err != nil { + return nil, err + } + return cc, nil + } + // commitments are fine + d.commitments[sc.Index] = poly + return nil, nil +} + +// ProcessComplaintCommits takes any ComplaintCommits revealed through +// ProcessSecretCommits() from other participants in QUAL. It returns the +// ReconstructCommits message that must be broadcasted to every other participant +// in QUAL so the polynomial in question can be reconstructed. +func (d *DistKeyGenerator) ProcessComplaintCommits(cc *ComplaintCommits) (*ReconstructCommits, error) { + issuer, ok := findPub(d.participants, cc.Index) + if !ok { + return nil, errors.New("dkg: commitcomplaint with unknown issuer") + } + + if !d.isInQUAL(cc.Index) { + return nil, errors.New("dkg: complaintcommit from non-qual member") + } + + if err := schnorr.Verify(d.suite, issuer, cc.Hash(d.suite), cc.Signature); err != nil { + return nil, err + } + + v, ok := d.verifiers[cc.DealerIndex] + if !ok { + return nil, errors.New("dkg: commitcomplaint linked to unknown verifier") + } + + // the verification should pass for the deal, and not with the secret + // commits. Verification 4) in DKG Rabin's paper. + if err := v.VerifyDeal(cc.Deal, false); err != nil { + return nil, fmt.Errorf("dkg: verifying deal: %s", err) + } + + secretCommits, ok := d.commitments[cc.DealerIndex] + if !ok { + return nil, errors.New("dkg: complaint about non received commitments") + } + + // the secret commits check should fail. Verification 5) in DKG Rabin's + // paper. + if secretCommits.Check(cc.Deal.SecShare) { + return nil, errors.New("dkg: invalid complaint, deal verifying") + } + + deal := v.Deal() + if deal == nil { + return nil, errors.New("dkg: complaint linked to non certified deal") + } + + delete(d.commitments, cc.DealerIndex) + rc := &ReconstructCommits{ + SessionID: cc.Deal.SessionID, + Index: d.index, + DealerIndex: cc.DealerIndex, + Share: deal.SecShare, + } + + msg := rc.Hash(d.suite) + var err error + rc.Signature, err = schnorr.Sign(d.suite, d.long, msg) + if err != nil { + return nil, err + } + d.pendingReconstruct[cc.DealerIndex] = append(d.pendingReconstruct[cc.DealerIndex], rc) + return rc, nil +} + +// ProcessReconstructCommits takes a ReconstructCommits message and stores it +// along any others. If there are enough messages to recover the coefficients of +// the public polynomials of the malicious dealer in question, then the +// polynomial is recovered. +func (d *DistKeyGenerator) ProcessReconstructCommits(rs *ReconstructCommits) error { + if _, ok := d.reconstructed[rs.DealerIndex]; ok { + // commitments already reconstructed, no need for other shares + return nil + } + _, ok := d.commitments[rs.DealerIndex] + if ok { + return errors.New("dkg: commitments not invalidated by any complaints") + } + + pub, ok := findPub(d.participants, rs.Index) + if !ok { + return errors.New("dkg: reconstruct commits with invalid verifier index") + } + + msg := rs.Hash(d.suite) + if err := schnorr.Verify(d.suite, pub, msg, rs.Signature); err != nil { + return err + } + + var arr = d.pendingReconstruct[rs.DealerIndex] + // check if packet is already received or not + // or if the session ID does not match the others + for _, r := range arr { + if r.Index == rs.Index { + return nil + } + if !bytes.Equal(r.SessionID, rs.SessionID) { + return errors.New("dkg: reconstruct commits invalid session id") + } + } + // add it to list of pending shares + arr = append(arr, rs) + d.pendingReconstruct[rs.DealerIndex] = arr + // check if we can reconstruct commitments + if len(arr) >= d.t { + var shares = make([]*share.PriShare, len(arr)) + for i, r := range arr { + shares[i] = r.Share + } + // error only happens when you have less than t shares, but we ensure + // there are more just before + pri, _ := share.RecoverPriPoly(d.suite, shares, d.t, len(d.participants)) + d.commitments[rs.DealerIndex] = pri.Commit(d.suite.Point().Base()) + // note it has been reconstructed. + d.reconstructed[rs.DealerIndex] = true + delete(d.pendingReconstruct, rs.DealerIndex) + } + return nil +} + +// Finished returns true if the DKG has operated the protocol correctly and has +// all necessary information to generate the DistKeyShare() by itself. It +// returns false otherwise. +func (d *DistKeyGenerator) Finished() bool { + var ret = true + var nb = 0 + d.qualIter(func(idx uint32, v *vss.Verifier) bool { + nb++ + // ALL QUAL members should have their commitments by now either given or + // reconstructed. + if _, ok := d.commitments[idx]; !ok { + ret = false + return false + } + return true + }) + return nb >= d.t && ret +} + +// DistKeyShare generates the distributed key relative to this receiver +// It throws an error if something is wrong such as not enough deals received. +// The shared secret can be computed when all deals have been sent and +// basically consists of a public point and a share. The public point is the sum +// of all aggregated individual public commits of each individual secrets. +// the share is evaluated from the global Private Polynomial, basically SUM of +// fj(i) for a receiver i. +func (d *DistKeyGenerator) DistKeyShare() (*DistKeyShare, error) { + if !d.Certified() { + return nil, errors.New("dkg: distributed key not certified") + } + + sh := d.suite.Scalar().Zero() + var pub *share.PubPoly + var err error + + d.qualIter(func(i uint32, v *vss.Verifier) bool { + // share of dist. secret = sum of all share received. + s := v.Deal().SecShare.V + sh = sh.Add(sh, s) + // Dist. public key = sum of all revealed commitments + poly, ok := d.commitments[i] + if !ok { + err = fmt.Errorf("dkg: protocol not finished: %d commitments missing", i) + return false + } + if pub == nil { + // first polynomial we see (instead of generating n empty commits) + pub = poly + return true + } + pub, err = pub.Add(poly) + return err == nil + }) + + if err != nil { + return nil, err + } + _, commits := pub.Info() + + return &DistKeyShare{ + Commits: commits, + Share: &share.PriShare{ + I: int(d.index), + V: sh, + }, + }, nil +} + +// Hash returns the hash value of this struct used in the signature process. +func (sc *SecretCommits) Hash(s Suite) []byte { + h := s.Hash() + _, _ = h.Write([]byte("secretcommits")) + _ = binary.Write(h, binary.LittleEndian, sc.Index) + for _, p := range sc.Commitments { + _, _ = p.MarshalTo(h) + } + return h.Sum(nil) +} + +// Hash returns the hash value of this struct used in the signature process. +func (cc *ComplaintCommits) Hash(s Suite) []byte { + h := s.Hash() + _, _ = h.Write([]byte("commitcomplaint")) + _ = binary.Write(h, binary.LittleEndian, cc.Index) + _ = binary.Write(h, binary.LittleEndian, cc.DealerIndex) + buff, _ := protobuf.Encode(cc.Deal) + _, _ = h.Write(buff) + return h.Sum(nil) +} + +// Hash returns the hash value of this struct used in the signature process. +func (rc *ReconstructCommits) Hash(s Suite) []byte { + h := s.Hash() + _, _ = h.Write([]byte("reconstructcommits")) + _ = binary.Write(h, binary.LittleEndian, rc.Index) + _ = binary.Write(h, binary.LittleEndian, rc.DealerIndex) + _, _ = h.Write(rc.Share.Hash(s)) + return h.Sum(nil) +} + +func findPub(list []kyber.Point, i uint32) (kyber.Point, bool) { + if i >= uint32(len(list)) { + return nil, false + } + return list[i], true +} diff --git a/kyber/share/dkg/rabin/dkg_test.go b/kyber/share/dkg/rabin/dkg_test.go new file mode 100644 index 0000000000..a90e0a03a9 --- /dev/null +++ b/kyber/share/dkg/rabin/dkg_test.go @@ -0,0 +1,695 @@ +package dkg + +import ( + "crypto/rand" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/share" + vss "go.dedis.ch/kyber/v3/share/vss/rabin" + "go.dedis.ch/kyber/v3/sign/schnorr" +) + +var suite = edwards25519.NewBlakeSHA256Ed25519() + +var nbParticipants = 7 + +var partPubs []kyber.Point +var partSec []kyber.Scalar + +var dkgs []*DistKeyGenerator + +func init() { + partPubs = make([]kyber.Point, nbParticipants) + partSec = make([]kyber.Scalar, nbParticipants) + for i := 0; i < nbParticipants; i++ { + sec, pub := genPair() + partPubs[i] = pub + partSec[i] = sec + } + dkgs = dkgGen() +} + +func TestDKGNewDistKeyGenerator(t *testing.T) { + long := partSec[0] + dkg, err := NewDistKeyGenerator(suite, long, partPubs, nbParticipants/2+1) + assert.Nil(t, err) + assert.NotNil(t, dkg.dealer) + // quick testing here; easier. + scs, err := dkg.SecretCommits() + assert.Nil(t, scs) + assert.Error(t, err) + + sec, _ := genPair() + _, err = NewDistKeyGenerator(suite, sec, partPubs, nbParticipants/2+1) + assert.Error(t, err) + +} + +func TestDKGDeal(t *testing.T) { + dkg := dkgs[0] + + dks, err := dkg.DistKeyShare() + assert.Error(t, err) + assert.Nil(t, dks) + + deals, err := dkg.Deals() + require.Nil(t, err) + assert.Len(t, deals, nbParticipants-1) + + for i := range deals { + assert.NotNil(t, deals[i]) + assert.Equal(t, uint32(0), deals[i].Index) + } + + v, ok := dkg.verifiers[dkg.index] + assert.True(t, ok) + assert.NotNil(t, v) +} + +func TestDKGProcessDeal(t *testing.T) { + dkgs = dkgGen() + dkg := dkgs[0] + deals, err := dkg.Deals() + require.Nil(t, err) + + rec := dkgs[1] + deal := deals[1] + assert.Equal(t, int(deal.Index), 0) + assert.Equal(t, uint32(1), rec.index) + + // verifier don't find itself + goodP := rec.participants + rec.participants = make([]kyber.Point, 0) + resp, err := rec.ProcessDeal(deal) + assert.Nil(t, resp) + assert.Error(t, err) + rec.participants = goodP + + // good deal + resp, err = rec.ProcessDeal(deal) + assert.NotNil(t, resp) + assert.Equal(t, true, resp.Response.Approved) + assert.Nil(t, err) + _, ok := rec.verifiers[deal.Index] + require.True(t, ok) + assert.Equal(t, uint32(0), resp.Index) + + // duplicate + resp, err = rec.ProcessDeal(deal) + assert.Nil(t, resp) + assert.Error(t, err) + + // wrong index + goodIdx := deal.Index + deal.Index = uint32(nbParticipants + 1) + resp, err = rec.ProcessDeal(deal) + assert.Nil(t, resp) + assert.Error(t, err) + deal.Index = goodIdx + + // wrong deal + goodSig := deal.Deal.Signature + deal.Deal.Signature = randomBytes(len(deal.Deal.Signature)) + resp, err = rec.ProcessDeal(deal) + assert.Nil(t, resp) + assert.Error(t, err) + deal.Deal.Signature = goodSig + +} + +func TestDKGProcessResponse(t *testing.T) { + // first peer generates wrong deal + // second peer processes it and returns a complaint + // first peer process the complaint + + dkgs = dkgGen() + dkg := dkgs[0] + idxRec := 1 + rec := dkgs[idxRec] + deal, err := dkg.dealer.PlaintextDeal(idxRec) + require.Nil(t, err) + + // give a wrong deal + goodSecret := deal.RndShare.V + deal.RndShare.V = suite.Scalar().Zero() + dd, err := dkg.Deals() + encD := dd[idxRec] + require.Nil(t, err) + resp, err := rec.ProcessDeal(encD) + assert.Nil(t, err) + require.NotNil(t, resp) + assert.Equal(t, false, resp.Response.Approved) + deal.RndShare.V = goodSecret + dd, _ = dkg.Deals() + encD = dd[idxRec] + + // no verifier tied to Response + v, ok := dkg.verifiers[0] + require.NotNil(t, v) + require.True(t, ok) + require.NotNil(t, v) + delete(dkg.verifiers, 0) + j, err := dkg.ProcessResponse(resp) + assert.Nil(t, j) + assert.NotNil(t, err) + dkg.verifiers[0] = v + + // invalid response + goodSig := resp.Response.Signature + resp.Response.Signature = randomBytes(len(goodSig)) + j, err = dkg.ProcessResponse(resp) + assert.Nil(t, j) + assert.Error(t, err) + resp.Response.Signature = goodSig + + // valid complaint from our deal + j, err = dkg.ProcessResponse(resp) + assert.NotNil(t, j) + assert.Nil(t, err) + + // valid complaint from another deal from another peer + dkg2 := dkgs[2] + require.Nil(t, err) + // fake a wrong deal + //deal20, err := dkg2.dealer.PlaintextDeal(0) + //require.Nil(t, err) + deal21, err := dkg2.dealer.PlaintextDeal(1) + require.Nil(t, err) + goodRnd21 := deal21.RndShare.V + deal21.RndShare.V = suite.Scalar().Zero() + deals2, err := dkg2.Deals() + require.Nil(t, err) + + resp12, err := rec.ProcessDeal(deals2[idxRec]) + assert.NotNil(t, resp) + assert.Equal(t, false, resp12.Response.Approved) + + deal21.RndShare.V = goodRnd21 + deals2, err = dkg2.Deals() + require.Nil(t, err) + + // give it to the first peer + // process dealer 2's deal + r, err := dkg.ProcessDeal(deals2[0]) + assert.Nil(t, err) + assert.NotNil(t, r) + + // process response from peer 1 + j, err = dkg.ProcessResponse(resp12) + assert.Nil(t, j) + assert.Nil(t, err) + + // Justification part: + // give the complaint to the dealer + j, err = dkg2.ProcessResponse(resp12) + assert.Nil(t, err) + assert.NotNil(t, j) + + // hack because all is local, and resp has been modified locally by dkg2's + // dealer, the status has became "justified" + resp12.Response.Approved = false + err = dkg.ProcessJustification(j) + assert.Nil(t, err) + + // remove verifiers + v = dkg.verifiers[j.Index] + delete(dkg.verifiers, j.Index) + err = dkg.ProcessJustification(j) + assert.Error(t, err) + dkg.verifiers[j.Index] = v + +} + +func TestDKGSecretCommits(t *testing.T) { + fullExchange(t) + + dkg := dkgs[0] + + sc, err := dkg.SecretCommits() + assert.Nil(t, err) + msg := sc.Hash(suite) + assert.Nil(t, schnorr.Verify(suite, dkg.pub, msg, sc.Signature)) + + dkg2 := dkgs[1] + // wrong index + goodIdx := sc.Index + sc.Index = uint32(nbParticipants + 1) + cc, err := dkg2.ProcessSecretCommits(sc) + assert.Nil(t, cc) + assert.Error(t, err) + sc.Index = goodIdx + + // not in qual: delete the verifier + goodV := dkg2.verifiers[uint32(0)] + delete(dkg2.verifiers, uint32(0)) + cc, err = dkg2.ProcessSecretCommits(sc) + assert.Nil(t, cc) + assert.Error(t, err) + dkg2.verifiers[uint32(0)] = goodV + + // invalid sig + goodSig := sc.Signature + sc.Signature = randomBytes(len(goodSig)) + cc, err = dkg2.ProcessSecretCommits(sc) + assert.Nil(t, cc) + assert.Error(t, err) + sc.Signature = goodSig + // invalid session id + goodSid := sc.SessionID + sc.SessionID = randomBytes(len(goodSid)) + cc, err = dkg2.ProcessSecretCommits(sc) + assert.Nil(t, cc) + assert.Error(t, err) + sc.SessionID = goodSid + + // wrong commitments + goodPoint := sc.Commitments[0] + sc.Commitments[0] = suite.Point().Null() + msg = sc.Hash(suite) + sig, err := schnorr.Sign(suite, dkg.long, msg) + require.Nil(t, err) + goodSig = sc.Signature + sc.Signature = sig + cc, err = dkg2.ProcessSecretCommits(sc) + assert.NotNil(t, cc) + assert.Nil(t, err) + sc.Commitments[0] = goodPoint + sc.Signature = goodSig + + // all fine + cc, err = dkg2.ProcessSecretCommits(sc) + assert.Nil(t, cc) + assert.Nil(t, err) +} + +func TestDKGComplaintCommits(t *testing.T) { + fullExchange(t) + + var scs []*SecretCommits + for _, dkg := range dkgs { + sc, err := dkg.SecretCommits() + require.Nil(t, err) + scs = append(scs, sc) + } + + for _, sc := range scs { + for _, dkg := range dkgs { + cc, err := dkg.ProcessSecretCommits(sc) + assert.Nil(t, err) + assert.Nil(t, cc) + } + } + + // change the sc for the second one + wrongSc := &SecretCommits{} + wrongSc.Index = scs[0].Index + wrongSc.SessionID = scs[0].SessionID + wrongSc.Commitments = make([]kyber.Point, len(scs[0].Commitments)) + copy(wrongSc.Commitments, scs[0].Commitments) + //goodScCommit := scs[0].Commitments[0] + wrongSc.Commitments[0] = suite.Point().Null() + msg := wrongSc.Hash(suite) + wrongSc.Signature, _ = schnorr.Sign(suite, dkgs[0].long, msg) + + dkg := dkgs[1] + cc, err := dkg.ProcessSecretCommits(wrongSc) + assert.Nil(t, err) + assert.NotNil(t, cc) + + dkg2 := dkgs[2] + // ComplaintCommits: wrong index + goodIndex := cc.Index + cc.Index = uint32(nbParticipants) + rc, err := dkg2.ProcessComplaintCommits(cc) + assert.Nil(t, rc) + assert.Error(t, err) + cc.Index = goodIndex + + // invalid signature + goodSig := cc.Signature + cc.Signature = randomBytes(len(cc.Signature)) + rc, err = dkg2.ProcessComplaintCommits(cc) + assert.Nil(t, rc) + assert.Error(t, err) + cc.Signature = goodSig + + // no verifiers + v := dkg2.verifiers[uint32(0)] + delete(dkg2.verifiers, uint32(0)) + rc, err = dkg2.ProcessComplaintCommits(cc) + assert.Nil(t, rc) + assert.Error(t, err) + dkg2.verifiers[uint32(0)] = v + + // deal does not verify + goodDeal := cc.Deal + cc.Deal = &vss.Deal{ + SessionID: goodDeal.SessionID, + SecShare: goodDeal.SecShare, + RndShare: goodDeal.RndShare, + T: goodDeal.T, + Commitments: goodDeal.Commitments, + } + rc, err = dkg2.ProcessComplaintCommits(cc) + assert.Nil(t, rc) + assert.Error(t, err) + cc.Deal = goodDeal + + // no commitments + sc := dkg2.commitments[uint32(0)] + delete(dkg2.commitments, uint32(0)) + rc, err = dkg2.ProcessComplaintCommits(cc) + assert.Nil(t, rc) + assert.Error(t, err) + dkg2.commitments[uint32(0)] = sc + + // secret commits are passing the check + rc, err = dkg2.ProcessComplaintCommits(cc) + assert.Nil(t, rc) + assert.Error(t, err) + + /* + TODO find a way to be the malicious guys,i.e. + make a deal which validates, but revealing the commitments coefficients makes + the check fails. + f is the secret polynomial + g is the "random" one + [f(i) + g(i)]*G == [F + G](i) + but + f(i)*G != F(i) + + goodV := cc.Deal.SecShare.V + goodDSig := cc.Deal.Signature + cc.Deal.SecShare.V = suite.Scalar().Zero() + msg = msgDeal(cc.Deal) + sig, _ := sign.Schnorr(suite, dkgs[cc.DealerIndex].long, msg) + cc.Deal.Signature = sig + msg = msgCommitComplaint(cc) + sig, _ = sign.Schnorr(suite, dkgs[cc.Index].long, msg) + goodCCSig := cc.Signature + cc.Signature = sig + rc, err = dkg2.ProcessComplaintCommits(cc) + assert.Nil(t, err) + assert.NotNil(t, rc) + cc.Deal.SecShare.V = goodV + cc.Deal.Signature = goodDSig + cc.Signature = goodCCSig + */ + +} + +func TestDKGReconstructCommits(t *testing.T) { + fullExchange(t) + + var scs []*SecretCommits + for _, dkg := range dkgs { + sc, err := dkg.SecretCommits() + require.Nil(t, err) + scs = append(scs, sc) + } + + // give the secret commits to all dkgs but the second one + for _, sc := range scs { + for _, dkg := range dkgs[2:] { + cc, err := dkg.ProcessSecretCommits(sc) + assert.Nil(t, err) + assert.Nil(t, cc) + } + } + + // peer 1 wants to reconstruct coeffs from dealer 1 + rc := &ReconstructCommits{ + Index: 1, + DealerIndex: 0, + Share: dkgs[uint32(1)].verifiers[uint32(0)].Deal().SecShare, + SessionID: dkgs[uint32(1)].verifiers[uint32(0)].Deal().SessionID, + } + msg := rc.Hash(suite) + rc.Signature, _ = schnorr.Sign(suite, dkgs[1].long, msg) + + dkg2 := dkgs[2] + // reconstructed already set + dkg2.reconstructed[0] = true + assert.Nil(t, dkg2.ProcessReconstructCommits(rc)) + delete(dkg2.reconstructed, uint32(0)) + + // commitments not invalidated by any complaints + assert.Error(t, dkg2.ProcessReconstructCommits(rc)) + delete(dkg2.commitments, uint32(0)) + + // invalid index + goodI := rc.Index + rc.Index = uint32(nbParticipants) + assert.Error(t, dkg2.ProcessReconstructCommits(rc)) + rc.Index = goodI + + // invalid sig + goodSig := rc.Signature + rc.Signature = randomBytes(len(goodSig)) + assert.Error(t, dkg2.ProcessReconstructCommits(rc)) + rc.Signature = goodSig + + // all fine + assert.Nil(t, dkg2.ProcessReconstructCommits(rc)) + + // packet already received + var found bool + for _, p := range dkg2.pendingReconstruct[rc.DealerIndex] { + if p.Index == rc.Index { + found = true + break + } + } + assert.True(t, found) + assert.False(t, dkg2.Finished()) + // generate enough secret commits to recover the secret + for _, dkg := range dkgs[2:] { + rc = &ReconstructCommits{ + SessionID: dkg.verifiers[uint32(0)].Deal().SessionID, + Index: dkg.index, + DealerIndex: 0, + Share: dkg.verifiers[uint32(0)].Deal().SecShare, + } + msg := rc.Hash(suite) + rc.Signature, _ = schnorr.Sign(suite, dkg.long, msg) + + if dkg2.reconstructed[uint32(0)] { + break + } + // invalid session ID + goodSID := rc.SessionID + rc.SessionID = randomBytes(len(goodSID)) + require.Error(t, dkg2.ProcessReconstructCommits(rc)) + rc.SessionID = goodSID + + _ = dkg2.ProcessReconstructCommits(rc) + } + assert.True(t, dkg2.reconstructed[uint32(0)]) + com := dkg2.commitments[uint32(0)] + assert.NotNil(t, com) + assert.Equal(t, dkgs[0].dealer.SecretCommit().String(), com.Commit().String()) + + assert.True(t, dkg2.Finished()) +} + +func TestSetTimeout(t *testing.T) { + dkgs = dkgGen() + // full secret sharing exchange + // 1. broadcast deals + resps := make([]*Response, 0, nbParticipants*nbParticipants) + for _, dkg := range dkgs { + deals, err := dkg.Deals() + require.Nil(t, err) + for i, d := range deals { + resp, err := dkgs[i].ProcessDeal(d) + require.Nil(t, err) + require.True(t, resp.Response.Approved) + resps = append(resps, resp) + } + } + + // 2. Broadcast responses + for _, resp := range resps { + for _, dkg := range dkgs { + if !dkg.verifiers[resp.Index].EnoughApprovals() { + // ignore messages about ourself + if resp.Response.Index == dkg.index { + continue + } + j, err := dkg.ProcessResponse(resp) + require.Nil(t, err) + require.Nil(t, j) + } + } + } + + // 3. make sure everyone has the same QUAL set + for _, dkg := range dkgs { + for _, dkg2 := range dkgs { + require.False(t, dkg.isInQUAL(dkg2.index)) + } + } + + for _, dkg := range dkgs { + dkg.SetTimeout() + } + + for _, dkg := range dkgs { + for _, dkg2 := range dkgs { + require.True(t, dkg.isInQUAL(dkg2.index)) + } + } + +} + +func TestDistKeyShare(t *testing.T) { + fullExchange(t) + + var scs []*SecretCommits + for i, dkg := range dkgs[:len(dkgs)-1] { + sc, err := dkg.SecretCommits() + require.Nil(t, err) + scs = append(scs, sc) + for j, dkg := range dkgs[:len(dkgs)-1] { + if i == j { + continue + } + cc, err := dkg.ProcessSecretCommits(sc) + require.Nil(t, err) + require.Nil(t, cc) + } + } + + // check that we can't get the dist key share before exchanging commitments + lastDkg := dkgs[len(dkgs)-1] + dks, err := lastDkg.DistKeyShare() + assert.Nil(t, dks) + assert.Error(t, err) + + for _, sc := range scs { + cc, err := lastDkg.ProcessSecretCommits(sc) + require.Nil(t, cc) + require.Nil(t, err) + } + + sc, err := lastDkg.SecretCommits() + require.Nil(t, err) + require.NotNil(t, sc) + + for _, dkg := range dkgs[:len(dkgs)-1] { + sc, err := dkg.ProcessSecretCommits(sc) + require.Nil(t, sc) + require.Nil(t, err) + + require.Equal(t, nbParticipants, len(dkg.QUAL())) + require.Equal(t, nbParticipants, len(dkg.commitments)) + } + + // missing one commitment + lastCommitment0 := lastDkg.commitments[0] + delete(lastDkg.commitments, uint32(0)) + dks, err = lastDkg.DistKeyShare() + assert.Nil(t, dks) + assert.Error(t, err) + lastDkg.commitments[uint32(0)] = lastCommitment0 + + // everyone should be finished + for _, dkg := range dkgs { + assert.True(t, dkg.Finished()) + } + // verify integrity of shares etc + dkss := make([]*DistKeyShare, nbParticipants) + for i, dkg := range dkgs { + dks, err := dkg.DistKeyShare() + require.NotNil(t, dks) + assert.Nil(t, err) + dkss[i] = dks + assert.Equal(t, dkg.index, uint32(dks.Share.I)) + } + + shares := make([]*share.PriShare, nbParticipants) + for i, dks := range dkss { + assert.True(t, checkDks(dks, dkss[0]), "dist key share not equal %d vs %d", dks.Share.I, 0) + shares[i] = dks.Share + } + + secret, err := share.RecoverSecret(suite, shares, nbParticipants, nbParticipants) + assert.Nil(t, err) + + commitSecret := suite.Point().Mul(secret, nil) + assert.Equal(t, dkss[0].Public().String(), commitSecret.String()) +} + +func dkgGen() []*DistKeyGenerator { + dkgs := make([]*DistKeyGenerator, nbParticipants) + for i := 0; i < nbParticipants; i++ { + dkg, err := NewDistKeyGenerator(suite, partSec[i], partPubs, nbParticipants/2+1) + if err != nil { + panic(err) + } + dkgs[i] = dkg + } + return dkgs +} + +func genPair() (kyber.Scalar, kyber.Point) { + sc := suite.Scalar().Pick(suite.RandomStream()) + return sc, suite.Point().Mul(sc, nil) +} + +func randomBytes(n int) []byte { + var buff = make([]byte, n) + _, _ = rand.Read(buff[:]) + return buff +} +func checkDks(dks1, dks2 *DistKeyShare) bool { + if len(dks1.Commits) != len(dks2.Commits) { + return false + } + for i, p := range dks1.Commits { + if !p.Equal(dks2.Commits[i]) { + return false + } + } + return true +} + +func fullExchange(t *testing.T) { + dkgs = dkgGen() + // full secret sharing exchange + // 1. broadcast deals + resps := make([]*Response, 0, nbParticipants*nbParticipants) + for _, dkg := range dkgs { + deals, err := dkg.Deals() + require.Nil(t, err) + for i, d := range deals { + resp, err := dkgs[i].ProcessDeal(d) + require.Nil(t, err) + require.Equal(t, true, resp.Response.Approved) + resps = append(resps, resp) + } + } + // 2. Broadcast responses + for _, resp := range resps { + for _, dkg := range dkgs { + // ignore all messages from ourself + if resp.Response.Index == dkg.index { + continue + } + j, err := dkg.ProcessResponse(resp) + require.Nil(t, err) + require.Nil(t, j) + } + } + // 3. make sure everyone has the same QUAL set + for _, dkg := range dkgs { + for _, dkg2 := range dkgs { + require.True(t, dkg.isInQUAL(dkg2.index)) + } + } + +} diff --git a/kyber/share/poly.go b/kyber/share/poly.go new file mode 100644 index 0000000000..47fc7adbff --- /dev/null +++ b/kyber/share/poly.go @@ -0,0 +1,523 @@ +// Package share implements Shamir secret sharing and polynomial commitments. +// Shamir's scheme allows you to split a secret value into multiple parts, so called +// shares, by evaluating a secret sharing polynomial at certain indices. The +// shared secret can only be reconstructed (via Lagrange interpolation) if a +// threshold of the participants provide their shares. A polynomial commitment +// scheme allows a committer to commit to a secret sharing polynomial so that +// a verifier can check the claimed evaluations of the committed polynomial. +// Both schemes of this package are core building blocks for more advanced +// secret sharing techniques. +package share + +import ( + "crypto/cipher" + "crypto/subtle" + "encoding/binary" + "errors" + "fmt" + "strings" + + "go.dedis.ch/kyber/v3" +) + +// Some error definitions +var errorGroups = errors.New("non-matching groups") +var errorCoeffs = errors.New("different number of coefficients") + +// PriShare represents a private share. +type PriShare struct { + I int // Index of the private share + V kyber.Scalar // Value of the private share +} + +func (p *PriShare) String() string { + return fmt.Sprintf("PriShare{%d:%v}", p.I, p.V) +} + +// Hash returns the hash representation of this share +func (p *PriShare) Hash(s kyber.HashFactory) []byte { + h := s.Hash() + _, _ = p.V.MarshalTo(h) + _ = binary.Write(h, binary.LittleEndian, p.I) + return h.Sum(nil) +} + +// PriPoly represents a secret sharing polynomial. +type PriPoly struct { + g kyber.Group // Cryptographic group + coeffs []kyber.Scalar // Coefficients of the polynomial +} + +// NewPriPoly creates a new secret sharing polynomial using the provided +// cryptographic group, the secret sharing threshold t, and the secret to be +// shared s. If s is nil, a new s is chosen using the provided randomness +// stream rand. +func NewPriPoly(group kyber.Group, t int, s kyber.Scalar, rand cipher.Stream) *PriPoly { + coeffs := make([]kyber.Scalar, t) + coeffs[0] = s + if coeffs[0] == nil { + coeffs[0] = group.Scalar().Pick(rand) + } + for i := 1; i < t; i++ { + coeffs[i] = group.Scalar().Pick(rand) + } + return &PriPoly{g: group, coeffs: coeffs} +} + +// CoefficientsToPriPoly returns a PriPoly based on the given coefficients +func CoefficientsToPriPoly(g kyber.Group, coeffs []kyber.Scalar) *PriPoly { + return &PriPoly{g: g, coeffs: coeffs} +} + +// Threshold returns the secret sharing threshold. +func (p *PriPoly) Threshold() int { + return len(p.coeffs) +} + +// Secret returns the shared secret p(0), i.e., the constant term of the polynomial. +func (p *PriPoly) Secret() kyber.Scalar { + return p.coeffs[0] +} + +// Eval computes the private share v = p(i). +func (p *PriPoly) Eval(i int) *PriShare { + xi := p.g.Scalar().SetInt64(1 + int64(i)) + v := p.g.Scalar().Zero() + for j := p.Threshold() - 1; j >= 0; j-- { + v.Mul(v, xi) + v.Add(v, p.coeffs[j]) + } + return &PriShare{i, v} +} + +// Shares creates a list of n private shares p(1),...,p(n). +func (p *PriPoly) Shares(n int) []*PriShare { + shares := make([]*PriShare, n) + for i := range shares { + shares[i] = p.Eval(i) + } + return shares +} + +// Add computes the component-wise sum of the polynomials p and q and returns it +// as a new polynomial. +func (p *PriPoly) Add(q *PriPoly) (*PriPoly, error) { + if p.g.String() != q.g.String() { + return nil, errorGroups + } + if p.Threshold() != q.Threshold() { + return nil, errorCoeffs + } + coeffs := make([]kyber.Scalar, p.Threshold()) + for i := range coeffs { + coeffs[i] = p.g.Scalar().Add(p.coeffs[i], q.coeffs[i]) + } + return &PriPoly{p.g, coeffs}, nil +} + +// Equal checks equality of two secret sharing polynomials p and q. If p and q are trivially +// unequal (e.g., due to mismatching cryptographic groups or polynomial size), this routine +// returns in variable time. Otherwise it runs in constant time regardless of whether it +// eventually returns true or false. +func (p *PriPoly) Equal(q *PriPoly) bool { + if p.g.String() != q.g.String() { + return false + } + if len(p.coeffs) != len(q.coeffs) { + return false + } + b := 1 + for i := 0; i < p.Threshold(); i++ { + pb, _ := p.coeffs[i].MarshalBinary() + qb, _ := q.coeffs[i].MarshalBinary() + b &= subtle.ConstantTimeCompare(pb, qb) + } + return b == 1 +} + +// Commit creates a public commitment polynomial for the given base point b or +// the standard base if b == nil. +func (p *PriPoly) Commit(b kyber.Point) *PubPoly { + commits := make([]kyber.Point, p.Threshold()) + for i := range commits { + commits[i] = p.g.Point().Mul(p.coeffs[i], b) + } + return &PubPoly{p.g, b, commits} +} + +// Mul multiples p and q together. The result is a polynomial of the sum of +// the two degrees of p and q. NOTE: it does not check for null coefficients +// after the multiplication, so the degree of the polynomial is "always" as +// described above. This is only for use in secret sharing schemes. It is not +// a general polynomial multiplication routine. +func (p *PriPoly) Mul(q *PriPoly) *PriPoly { + d1 := len(p.coeffs) - 1 + d2 := len(q.coeffs) - 1 + newDegree := d1 + d2 + coeffs := make([]kyber.Scalar, newDegree+1) + for i := range coeffs { + coeffs[i] = p.g.Scalar().Zero() + } + for i := range p.coeffs { + for j := range q.coeffs { + tmp := p.g.Scalar().Mul(p.coeffs[i], q.coeffs[j]) + coeffs[i+j] = tmp.Add(coeffs[i+j], tmp) + } + } + return &PriPoly{p.g, coeffs} +} + +// Coefficients return the list of coefficients representing p. This +// information is generally PRIVATE and should not be revealed to a third party +// lightly. +func (p *PriPoly) Coefficients() []kyber.Scalar { + return p.coeffs +} + +// RecoverSecret reconstructs the shared secret p(0) from a list of private +// shares using Lagrange interpolation. +func RecoverSecret(g kyber.Group, shares []*PriShare, t, n int) (kyber.Scalar, error) { + x, y := xyScalar(g, shares, t, n) + if len(x) < t { + return nil, errors.New("share: not enough shares to recover secret") + } + + acc := g.Scalar().Zero() + num := g.Scalar() + den := g.Scalar() + tmp := g.Scalar() + + for i, xi := range x { + yi := y[i] + num.Set(yi) + den.One() + for j, xj := range x { + if i == j { + continue + } + num.Mul(num, xj) + den.Mul(den, tmp.Sub(xj, xi)) + } + acc.Add(acc, num.Div(num, den)) + } + + return acc, nil +} + +// xyScalar returns the list of (x_i, y_i) pairs indexed. The first map returned +// is the list of x_i and the second map is the list of y_i, both indexed in +// their respective map at index i. +func xyScalar(g kyber.Group, shares []*PriShare, t, n int) (map[int]kyber.Scalar, map[int]kyber.Scalar) { + // we are sorting first the shares since the shares may be unrelated for + // some applications. In this case, all participants needs to interpolate on + // the exact same order shares. + // XXX naive n^2 sorting => move that to inplace golang native sort + sorted := make([]*PriShare, n) + for i := 0; i < len(shares); i++ { + if shares[i] != nil { + sorted[shares[i].I] = shares[i] + } + } + if len(sorted) < len(shares) { + panic("that should not happen") + } + + x := make(map[int]kyber.Scalar) + y := make(map[int]kyber.Scalar) + for _, s := range sorted { + if s == nil || s.V == nil || s.I < 0 || n <= s.I { + continue + } + idx := s.I + x[idx] = g.Scalar().SetInt64(int64(idx + 1)) + y[idx] = s.V + if len(x) == t { + break + } + } + return x, y +} + +func minusConst(g kyber.Group, c kyber.Scalar) *PriPoly { + neg := g.Scalar().Neg(c) + return &PriPoly{ + g: g, + coeffs: []kyber.Scalar{neg, g.Scalar().One()}, + } +} + +// RecoverPriPoly takes a list of shares and the parameters t and n to +// reconstruct the secret polynomial completely, i.e., all private +// coefficients. It is up to the caller to make sure that there are enough +// shares to correctly re-construct the polynomial. There must be at least t +// shares. +func RecoverPriPoly(g kyber.Group, shares []*PriShare, t, n int) (*PriPoly, error) { + x, y := xyScalar(g, shares, t, n) + if len(x) != t { + return nil, errors.New("share: not enough shares to recover private polynomial") + } + + var accPoly *PriPoly + var err error + //den := g.Scalar() + // Notations follow the Wikipedia article on Lagrange interpolation + // https://en.wikipedia.org/wiki/Lagrange_polynomial + for j := range x { + basis := lagrangeBasis(g, j, x) + for i := range basis.coeffs { + basis.coeffs[i] = basis.coeffs[i].Mul(basis.coeffs[i], y[j]) + } + + if accPoly == nil { + accPoly = basis + continue + } + + // add all L_j * y_j together + accPoly, err = accPoly.Add(basis) + if err != nil { + return nil, err + } + } + return accPoly, nil +} + +func (p *PriPoly) String() string { + var strs = make([]string, len(p.coeffs)) + for i, c := range p.coeffs { + strs[i] = c.String() + } + return "[ " + strings.Join(strs, ", ") + " ]" +} + +// PubShare represents a public share. +type PubShare struct { + I int // Index of the public share + V kyber.Point // Value of the public share +} + +// Hash returns the hash representation of this share. +func (p *PubShare) Hash(s kyber.HashFactory) []byte { + h := s.Hash() + _, _ = p.V.MarshalTo(h) + _ = binary.Write(h, binary.LittleEndian, p.I) + return h.Sum(nil) +} + +// PubPoly represents a public commitment polynomial to a secret sharing polynomial. +type PubPoly struct { + g kyber.Group // Cryptographic group + b kyber.Point // Base point, nil for standard base + commits []kyber.Point // Commitments to coefficients of the secret sharing polynomial +} + +// NewPubPoly creates a new public commitment polynomial. +func NewPubPoly(g kyber.Group, b kyber.Point, commits []kyber.Point) *PubPoly { + return &PubPoly{g, b, commits} +} + +// Info returns the base point and the commitments to the polynomial coefficients. +func (p *PubPoly) Info() (base kyber.Point, commits []kyber.Point) { + return p.b, p.commits +} + +// Threshold returns the secret sharing threshold. +func (p *PubPoly) Threshold() int { + return len(p.commits) +} + +// Commit returns the secret commitment p(0), i.e., the constant term of the polynomial. +func (p *PubPoly) Commit() kyber.Point { + return p.commits[0] +} + +// Eval computes the public share v = p(i). +func (p *PubPoly) Eval(i int) *PubShare { + xi := p.g.Scalar().SetInt64(1 + int64(i)) // x-coordinate of this share + v := p.g.Point().Null() + for j := p.Threshold() - 1; j >= 0; j-- { + v.Mul(xi, v) + v.Add(v, p.commits[j]) + } + return &PubShare{i, v} +} + +// Shares creates a list of n public commitment shares p(1),...,p(n). +func (p *PubPoly) Shares(n int) []*PubShare { + shares := make([]*PubShare, n) + for i := range shares { + shares[i] = p.Eval(i) + } + return shares +} + +// Add computes the component-wise sum of the polynomials p and q and returns it +// as a new polynomial. NOTE: If the base points p.b and q.b are different then the +// base point of the resulting PubPoly cannot be computed without knowing the +// discrete logarithm between p.b and q.b. In this particular case, we are using +// p.b as a default value which of course does not correspond to the correct +// base point and thus should not be used in further computations. +func (p *PubPoly) Add(q *PubPoly) (*PubPoly, error) { + if p.g.String() != q.g.String() { + return nil, errorGroups + } + + if p.Threshold() != q.Threshold() { + return nil, errorCoeffs + } + + commits := make([]kyber.Point, p.Threshold()) + for i := range commits { + commits[i] = p.g.Point().Add(p.commits[i], q.commits[i]) + } + + return &PubPoly{p.g, p.b, commits}, nil +} + +// Equal checks equality of two public commitment polynomials p and q. If p and +// q are trivially unequal (e.g., due to mismatching cryptographic groups), +// this routine returns in variable time. Otherwise it runs in constant time +// regardless of whether it eventually returns true or false. +func (p *PubPoly) Equal(q *PubPoly) bool { + if p.g.String() != q.g.String() { + return false + } + b := 1 + for i := 0; i < p.Threshold(); i++ { + pb, _ := p.commits[i].MarshalBinary() + qb, _ := q.commits[i].MarshalBinary() + b &= subtle.ConstantTimeCompare(pb, qb) + } + return b == 1 +} + +// Check a private share against a public commitment polynomial. +func (p *PubPoly) Check(s *PriShare) bool { + pv := p.Eval(s.I) + ps := p.g.Point().Mul(s.V, p.b) + return pv.V.Equal(ps) +} + +// xyCommits is the public version of xScalars. +func xyCommit(g kyber.Group, shares []*PubShare, t, n int) (map[int]kyber.Scalar, map[int]kyber.Point) { + // we are sorting first the shares since the shares may be unrelated for + // some applications. In this case, all participants needs to interpolate on + // the exact same order shares. + // XXX naive n^2 sorting => move that to inplace golang native sort + sorted := make([]*PubShare, n) + for i := 0; i < len(shares); i++ { + if shares[i] != nil { + sorted[shares[i].I] = shares[i] + } + } + + if len(sorted) < len(shares) { + panic("that should not happen") + } + x := make(map[int]kyber.Scalar) + y := make(map[int]kyber.Point) + + for _, s := range sorted { + if s == nil || s.V == nil || s.I < 0 || n <= s.I { + continue + } + idx := s.I + x[idx] = g.Scalar().SetInt64(int64(idx + 1)) + y[idx] = s.V + if len(x) == t { + break + } + } + return x, y +} + +// RecoverCommit reconstructs the secret commitment p(0) from a list of public +// shares using Lagrange interpolation. +func RecoverCommit(g kyber.Group, shares []*PubShare, t, n int) (kyber.Point, error) { + x, y := xyCommit(g, shares, t, n) + if len(x) < t { + return nil, errors.New("share: not enough good public shares to reconstruct secret commitment") + } + + num := g.Scalar() + den := g.Scalar() + tmp := g.Scalar() + Acc := g.Point().Null() + Tmp := g.Point() + + for i, xi := range x { + num.One() + den.One() + for j, xj := range x { + if i == j { + continue + } + num.Mul(num, xj) + den.Mul(den, tmp.Sub(xj, xi)) + } + Tmp.Mul(num.Div(num, den), y[i]) + Acc.Add(Acc, Tmp) + } + + return Acc, nil +} + +// RecoverPubPoly reconstructs the full public polynomial from a set of public +// shares using Lagrange interpolation. +func RecoverPubPoly(g kyber.Group, shares []*PubShare, t, n int) (*PubPoly, error) { + x, y := xyCommit(g, shares, t, n) + if len(x) < t { + return nil, errors.New("share: not enough good public shares to reconstruct secret commitment") + } + + var accPoly *PubPoly + var err error + + for j := range x { + basis := lagrangeBasis(g, j, x) + + // compute the L_j * y_j polynomial in point space + tmp := basis.Commit(y[j]) + if accPoly == nil { + accPoly = tmp + continue + } + + // add all L_j * y_j together + accPoly, err = accPoly.Add(tmp) + if err != nil { + return nil, err + } + } + + return accPoly, nil + +} + +// lagrangeBasis returns a PriPoly containing the Lagrange coefficients for the +// i-th position. xs is a mapping between the indices and the values that the +// interpolation is using, computed with xyScalar(). +func lagrangeBasis(g kyber.Group, i int, xs map[int]kyber.Scalar) *PriPoly { + var basis = &PriPoly{ + g: g, + coeffs: []kyber.Scalar{g.Scalar().One()}, + } + // compute lagrange basis l_j + den := g.Scalar().One() + var acc = g.Scalar().One() + for m, xm := range xs { + if i == m { + continue + } + basis = basis.Mul(minusConst(g, xm)) + den.Sub(xs[i], xm) // den = xi - xm + den.Inv(den) // den = 1 / den + acc.Mul(acc, den) // acc = acc * den + } + + // multiply all coefficients by the denominator + for i := range basis.coeffs { + basis.coeffs[i] = basis.coeffs[i].Mul(basis.coeffs[i], acc) + } + return basis +} diff --git a/kyber/share/poly_test.go b/kyber/share/poly_test.go new file mode 100644 index 0000000000..b06fb7a8f6 --- /dev/null +++ b/kyber/share/poly_test.go @@ -0,0 +1,458 @@ +package share + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" +) + +func TestSecretRecovery(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + poly := NewPriPoly(g, t, nil, g.RandomStream()) + shares := poly.Shares(n) + + recovered, err := RecoverSecret(g, shares, t, n) + if err != nil { + test.Fatal(err) + } + + if !recovered.Equal(poly.Secret()) { + test.Fatal("recovered secret does not match initial value") + } +} +func TestSecretRecoveryDelete(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + poly := NewPriPoly(g, t, nil, g.RandomStream()) + shares := poly.Shares(n) + + // Corrupt a few shares + shares[2] = nil + shares[5] = nil + shares[7] = nil + shares[8] = nil + + recovered, err := RecoverSecret(g, shares, t, n) + if err != nil { + test.Fatal(err) + } + + if !recovered.Equal(poly.Secret()) { + test.Fatal("recovered secret does not match initial value") + } +} + +func TestSecretRecoveryDeleteFail(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + + poly := NewPriPoly(g, t, nil, g.RandomStream()) + shares := poly.Shares(n) + + // Corrupt one more share than acceptable + shares[1] = nil + shares[2] = nil + shares[5] = nil + shares[7] = nil + shares[8] = nil + + _, err := RecoverSecret(g, shares, t, n) + if err == nil { + test.Fatal("recovered secret unexpectably") + } +} + +func TestSecretPolyEqual(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + + p1 := NewPriPoly(g, t, nil, g.RandomStream()) + p2 := NewPriPoly(g, t, nil, g.RandomStream()) + p3 := NewPriPoly(g, t, nil, g.RandomStream()) + + p12, _ := p1.Add(p2) + p13, _ := p1.Add(p3) + + p123, _ := p12.Add(p3) + p132, _ := p13.Add(p2) + + if !p123.Equal(p132) { + test.Fatal("private polynomials not equal") + } +} + +func TestPublicCheck(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + + priPoly := NewPriPoly(g, t, nil, g.RandomStream()) + priShares := priPoly.Shares(n) + pubPoly := priPoly.Commit(nil) + + for i, share := range priShares { + if !pubPoly.Check(share) { + test.Fatalf("private share %v not valid with respect to the public commitment polynomial", i) + } + } +} + +func TestPublicRecovery(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + + priPoly := NewPriPoly(g, t, nil, g.RandomStream()) + pubPoly := priPoly.Commit(nil) + pubShares := pubPoly.Shares(n) + + recovered, err := RecoverCommit(g, pubShares, t, n) + if err != nil { + test.Fatal(err) + } + + if !recovered.Equal(pubPoly.Commit()) { + test.Fatal("recovered commit does not match initial value") + } + + polyRecovered, err := RecoverPubPoly(g, pubShares, t, n) + if err != nil { + test.Fatal(err) + } + + require.True(test, pubPoly.Equal(polyRecovered)) +} + +func TestPublicRecoveryDelete(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + + priPoly := NewPriPoly(g, t, nil, g.RandomStream()) + pubPoly := priPoly.Commit(nil) + shares := pubPoly.Shares(n) + + // Corrupt a few shares + shares[2] = nil + shares[5] = nil + shares[7] = nil + shares[8] = nil + + recovered, err := RecoverCommit(g, shares, t, n) + if err != nil { + test.Fatal(err) + } + + if !recovered.Equal(pubPoly.Commit()) { + test.Fatal("recovered commit does not match initial value") + } +} + +func TestPublicRecoveryDeleteFail(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + + priPoly := NewPriPoly(g, t, nil, g.RandomStream()) + pubPoly := priPoly.Commit(nil) + shares := pubPoly.Shares(n) + + // Corrupt one more share than acceptable + shares[1] = nil + shares[2] = nil + shares[5] = nil + shares[7] = nil + shares[8] = nil + + _, err := RecoverCommit(g, shares, t, n) + if err == nil { + test.Fatal("recovered commit unexpectably") + } +} + +func TestPrivateAdd(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + + p := NewPriPoly(g, t, nil, g.RandomStream()) + q := NewPriPoly(g, t, nil, g.RandomStream()) + + r, err := p.Add(q) + if err != nil { + test.Fatal(err) + } + + ps := p.Secret() + qs := q.Secret() + rs := g.Scalar().Add(ps, qs) + + if !rs.Equal(r.Secret()) { + test.Fatal("addition of secret sharing polynomials failed") + } +} + +func TestPublicAdd(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + + G := g.Point().Pick(g.RandomStream()) + H := g.Point().Pick(g.RandomStream()) + + p := NewPriPoly(g, t, nil, g.RandomStream()) + q := NewPriPoly(g, t, nil, g.RandomStream()) + + P := p.Commit(G) + Q := q.Commit(H) + + R, err := P.Add(Q) + if err != nil { + test.Fatal(err) + } + + shares := R.Shares(n) + recovered, err := RecoverCommit(g, shares, t, n) + if err != nil { + test.Fatal(err) + } + + x := P.Commit() + y := Q.Commit() + z := g.Point().Add(x, y) + + if !recovered.Equal(z) { + test.Fatal("addition of public commitment polynomials failed") + } +} + +func TestPublicPolyEqual(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + + G := g.Point().Pick(g.RandomStream()) + + p1 := NewPriPoly(g, t, nil, g.RandomStream()) + p2 := NewPriPoly(g, t, nil, g.RandomStream()) + p3 := NewPriPoly(g, t, nil, g.RandomStream()) + + P1 := p1.Commit(G) + P2 := p2.Commit(G) + P3 := p3.Commit(G) + + P12, _ := P1.Add(P2) + P13, _ := P1.Add(P3) + + P123, _ := P12.Add(P3) + P132, _ := P13.Add(P2) + + if !P123.Equal(P132) { + test.Fatal("public polynomials not equal") + } +} + +func TestPriPolyMul(test *testing.T) { + suite := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + a := NewPriPoly(suite, t, nil, suite.RandomStream()) + b := NewPriPoly(suite, t, nil, suite.RandomStream()) + + c := a.Mul(b) + assert.Equal(test, len(a.coeffs)+len(b.coeffs)-1, len(c.coeffs)) + nul := suite.Scalar().Zero() + for _, coeff := range c.coeffs { + assert.NotEqual(test, nul.String(), coeff.String()) + } + + a0 := a.coeffs[0] + b0 := b.coeffs[0] + mul := suite.Scalar().Mul(b0, a0) + c0 := c.coeffs[0] + assert.Equal(test, c0.String(), mul.String()) + + at := a.coeffs[len(a.coeffs)-1] + bt := b.coeffs[len(b.coeffs)-1] + mul = suite.Scalar().Mul(at, bt) + ct := c.coeffs[len(c.coeffs)-1] + assert.Equal(test, ct.String(), mul.String()) +} + +func TestRecoverPriPoly(test *testing.T) { + suite := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + a := NewPriPoly(suite, t, nil, suite.RandomStream()) + + shares := a.Shares(n) + reverses := make([]*PriShare, len(shares)) + l := len(shares) - 1 + for i := range shares { + reverses[l-i] = shares[i] + } + recovered, err := RecoverPriPoly(suite, shares, t, n) + assert.Nil(test, err) + + reverseRecovered, err := RecoverPriPoly(suite, reverses, t, n) + assert.Nil(test, err) + + for i := 0; i < t; i++ { + assert.Equal(test, recovered.Eval(i).V.String(), a.Eval(i).V.String()) + assert.Equal(test, reverseRecovered.Eval(i).V.String(), a.Eval(i).V.String()) + } +} + +func TestPriPolyCoefficients(test *testing.T) { + suite := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + a := NewPriPoly(suite, t, nil, suite.RandomStream()) + + coeffs := a.Coefficients() + require.Len(test, coeffs, t) + + b := CoefficientsToPriPoly(suite, coeffs) + require.Equal(test, a.coeffs, b.coeffs) + +} + +func TestRefreshDKG(test *testing.T) { + g := edwards25519.NewBlakeSHA256Ed25519() + n := 10 + t := n/2 + 1 + + // Run an n-fold Pedersen VSS (= DKG) + priPolys := make([]*PriPoly, n) + priShares := make([][]*PriShare, n) + pubPolys := make([]*PubPoly, n) + pubShares := make([][]*PubShare, n) + for i := 0; i < n; i++ { + priPolys[i] = NewPriPoly(g, t, nil, g.RandomStream()) + priShares[i] = priPolys[i].Shares(n) + pubPolys[i] = priPolys[i].Commit(nil) + pubShares[i] = pubPolys[i].Shares(n) + } + + // Verify VSS shares + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + sij := priShares[i][j] + // s_ij * G + sijG := g.Point().Base().Mul(sij.V, nil) + require.True(test, sijG.Equal(pubShares[i][j].V)) + } + } + + // Create private DKG shares + dkgShares := make([]*PriShare, n) + for i := 0; i < n; i++ { + acc := g.Scalar().Zero() + for j := 0; j < n; j++ { // assuming all participants are in the qualified set + acc = g.Scalar().Add(acc, priShares[j][i].V) + } + dkgShares[i] = &PriShare{i, acc} + } + + // Create public DKG commitments (= verification vector) + dkgCommits := make([]kyber.Point, t) + for k := 0; k < t; k++ { + acc := g.Point().Null() + for i := 0; i < n; i++ { // assuming all participants are in the qualified set + _, coeff := pubPolys[i].Info() + acc = g.Point().Add(acc, coeff[k]) + } + dkgCommits[k] = acc + } + + // Check that the private DKG shares verify against the public DKG commits + dkgPubPoly := NewPubPoly(g, nil, dkgCommits) + for i := 0; i < n; i++ { + require.True(test, dkgPubPoly.Check(dkgShares[i])) + } + + // Start verifiable resharing process + subPriPolys := make([]*PriPoly, n) + subPriShares := make([][]*PriShare, n) + subPubPolys := make([]*PubPoly, n) + subPubShares := make([][]*PubShare, n) + + // Create subshares and subpolys + for i := 0; i < n; i++ { + subPriPolys[i] = NewPriPoly(g, t, dkgShares[i].V, g.RandomStream()) + subPriShares[i] = subPriPolys[i].Shares(n) + subPubPolys[i] = subPriPolys[i].Commit(nil) + subPubShares[i] = subPubPolys[i].Shares(n) + require.True(test, g.Point().Mul(subPriShares[i][0].V, nil).Equal(subPubShares[i][0].V)) + } + + // Handout shares to new nodes column-wise and verify them + newDKGShares := make([]*PriShare, n) + for i := 0; i < n; i++ { + tmpPriShares := make([]*PriShare, n) // column-wise reshuffled sub-shares + tmpPubShares := make([]*PubShare, n) // public commitments to old DKG private shares + for j := 0; j < n; j++ { + // Check 1: Verify that the received individual private subshares s_ji + // is correct by evaluating the public commitment vector + tmpPriShares[j] = &PriShare{I: j, V: subPriShares[j][i].V} // Shares that participant i gets from j + require.True(test, g.Point().Mul(tmpPriShares[j].V, nil).Equal(subPubPolys[j].Eval(i).V)) + + // Check 2: Verify that the received sub public shares are + // commitments to the original secret + tmpPubShares[j] = dkgPubPoly.Eval(j) + require.True(test, tmpPubShares[j].V.Equal(subPubPolys[j].Commit())) + } + // Check 3: Verify that the received public shares interpolate to the + // original DKG public key + com, err := RecoverCommit(g, tmpPubShares, t, n) + require.NoError(test, err) + require.True(test, dkgCommits[0].Equal(com)) + + // Compute the refreshed private DKG share of node i + s, err := RecoverSecret(g, tmpPriShares, t, n) + require.NoError(test, err) + newDKGShares[i] = &PriShare{I: i, V: s} + } + + // Refresh the DKG commitments (= verification vector) + newDKGCommits := make([]kyber.Point, t) + for i := 0; i < t; i++ { + pubShares := make([]*PubShare, n) + for j := 0; j < n; j++ { + _, c := subPubPolys[j].Info() + pubShares[j] = &PubShare{I: j, V: c[i]} + } + com, err := RecoverCommit(g, pubShares, t, n) + require.NoError(test, err) + newDKGCommits[i] = com + } + + // Check that the old and new DKG public keys are the same + require.True(test, dkgCommits[0].Equal(newDKGCommits[0])) + + // Check that the old and new DKG private shares are different + for i := 0; i < n; i++ { + require.False(test, dkgShares[i].V.Equal(newDKGShares[i].V)) + } + + // Check that the refreshed private DKG shares verify against the refreshed public DKG commits + q := NewPubPoly(g, nil, newDKGCommits) + for i := 0; i < n; i++ { + require.True(test, q.Check(newDKGShares[i])) + } + + // Recover the private polynomial + refreshedPriPoly, err := RecoverPriPoly(g, newDKGShares, t, n) + require.NoError(test, err) + + // Check that the secret and the corresponding (old) public commit match + require.True(test, g.Point().Mul(refreshedPriPoly.Secret(), nil).Equal(dkgCommits[0])) +} diff --git a/kyber/share/pvss/pvss.go b/kyber/share/pvss/pvss.go new file mode 100644 index 0000000000..8c8fc8cfee --- /dev/null +++ b/kyber/share/pvss/pvss.go @@ -0,0 +1,190 @@ +// Package pvss implements public verifiable secret sharing as introduced in +// "A Simple Publicly Verifiable Secret Sharing Scheme and its Application to +// Electronic Voting" by Berry Schoenmakers. In comparison to regular verifiable +// secret sharing schemes, PVSS enables any third party to verify shares +// distributed by a dealer using zero-knowledge proofs. PVSS runs in three steps: +// 1. The dealer creates a list of encrypted public verifiable shares using +// EncShares() and distributes them to the trustees. +// 2. Upon the announcement that the secret should be released, each trustee +// uses DecShare() to first verify and, if valid, decrypt his share. +// 3. Once a threshold of decrypted shares has been released, anyone can +// verify them and, if enough shares are valid, recover the shared secret +// using RecoverSecret(). +package pvss + +import ( + "errors" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/proof/dleq" + "go.dedis.ch/kyber/v3/share" +) + +// Suite describes the functionalities needed by this package in order to +// function correctly. +type Suite interface { + kyber.Group + kyber.HashFactory + kyber.Encoding + kyber.XOFFactory + kyber.Random +} + +// Some error definitions. +var errorTooFewShares = errors.New("not enough shares to recover secret") +var errorDifferentLengths = errors.New("inputs of different lengths") +var errorEncVerification = errors.New("verification of encrypted share failed") +var errorDecVerification = errors.New("verification of decrypted share failed") + +// PubVerShare is a public verifiable share. +type PubVerShare struct { + S share.PubShare // Share + P dleq.Proof // Proof +} + +// EncShares creates a list of encrypted publicly verifiable PVSS shares for +// the given secret and the list of public keys X using the sharing threshold +// t and the base point H. The function returns the list of shares and the +// public commitment polynomial. +func EncShares(suite Suite, H kyber.Point, X []kyber.Point, secret kyber.Scalar, t int) (shares []*PubVerShare, commit *share.PubPoly, err error) { + n := len(X) + encShares := make([]*PubVerShare, n) + + // Create secret sharing polynomial + priPoly := share.NewPriPoly(suite, t, secret, suite.RandomStream()) + + // Create secret set of shares + priShares := priPoly.Shares(n) + + // Create public polynomial commitments with respect to basis H + pubPoly := priPoly.Commit(H) + + // Prepare data for encryption consistency proofs ... + indices := make([]int, n) + values := make([]kyber.Scalar, n) + HS := make([]kyber.Point, n) + for i := 0; i < n; i++ { + indices[i] = priShares[i].I + values[i] = priShares[i].V + HS[i] = H + } + + // Create NIZK discrete-logarithm equality proofs + proofs, _, sX, err := dleq.NewDLEQProofBatch(suite, HS, X, values) + if err != nil { + return nil, nil, err + } + + for i := 0; i < n; i++ { + ps := &share.PubShare{I: indices[i], V: sX[i]} + encShares[i] = &PubVerShare{*ps, *proofs[i]} + } + + return encShares, pubPoly, nil +} + +// VerifyEncShare checks that the encrypted share sX satisfies +// log_{H}(sH) == log_{X}(sX) where sH is the public commitment computed by +// evaluating the public commitment polynomial at the encrypted share's index i. +func VerifyEncShare(suite Suite, H kyber.Point, X kyber.Point, sH kyber.Point, encShare *PubVerShare) error { + if err := encShare.P.Verify(suite, H, X, sH, encShare.S.V); err != nil { + return errorEncVerification + } + return nil +} + +// VerifyEncShareBatch provides the same functionality as VerifyEncShare but for +// slices of encrypted shares. The function returns the valid encrypted shares +// together with the corresponding public keys. +func VerifyEncShareBatch(suite Suite, H kyber.Point, X []kyber.Point, sH []kyber.Point, encShares []*PubVerShare) ([]kyber.Point, []*PubVerShare, error) { + if len(X) != len(sH) || len(sH) != len(encShares) { + return nil, nil, errorDifferentLengths + } + var K []kyber.Point // good public keys + var E []*PubVerShare // good encrypted shares + for i := 0; i < len(X); i++ { + if err := VerifyEncShare(suite, H, X[i], sH[i], encShares[i]); err == nil { + K = append(K, X[i]) + E = append(E, encShares[i]) + } + } + return K, E, nil +} + +// DecShare first verifies the encrypted share against the encryption +// consistency proof and, if valid, decrypts it and creates a decryption +// consistency proof. +func DecShare(suite Suite, H kyber.Point, X kyber.Point, sH kyber.Point, x kyber.Scalar, encShare *PubVerShare) (*PubVerShare, error) { + if err := VerifyEncShare(suite, H, X, sH, encShare); err != nil { + return nil, err + } + G := suite.Point().Base() + V := suite.Point().Mul(suite.Scalar().Inv(x), encShare.S.V) // decryption: x^{-1} * (xS) + ps := &share.PubShare{I: encShare.S.I, V: V} + P, _, _, err := dleq.NewDLEQProof(suite, G, V, x) + if err != nil { + return nil, err + } + return &PubVerShare{*ps, *P}, nil +} + +// DecShareBatch provides the same functionality as DecShare but for slices of +// encrypted shares. The function returns the valid encrypted and decrypted +// shares as well as the corresponding public keys. +func DecShareBatch(suite Suite, H kyber.Point, X []kyber.Point, sH []kyber.Point, x kyber.Scalar, encShares []*PubVerShare) ([]kyber.Point, []*PubVerShare, []*PubVerShare, error) { + if len(X) != len(sH) || len(sH) != len(encShares) { + return nil, nil, nil, errorDifferentLengths + } + var K []kyber.Point // good public keys + var E []*PubVerShare // good encrypted shares + var D []*PubVerShare // good decrypted shares + for i := 0; i < len(encShares); i++ { + if ds, err := DecShare(suite, H, X[i], sH[i], x, encShares[i]); err == nil { + K = append(K, X[i]) + E = append(E, encShares[i]) + D = append(D, ds) + } + } + return K, E, D, nil +} + +// VerifyDecShare checks that the decrypted share sG satisfies +// log_{G}(X) == log_{sG}(sX). Note that X = xG and sX = s(xG) = x(sG). +func VerifyDecShare(suite Suite, G kyber.Point, X kyber.Point, encShare *PubVerShare, decShare *PubVerShare) error { + if err := decShare.P.Verify(suite, G, decShare.S.V, X, encShare.S.V); err != nil { + return errorDecVerification + } + return nil +} + +// VerifyDecShareBatch provides the same functionality as VerifyDecShare but for +// slices of decrypted shares. The function returns the the valid decrypted shares. +func VerifyDecShareBatch(suite Suite, G kyber.Point, X []kyber.Point, encShares []*PubVerShare, decShares []*PubVerShare) ([]*PubVerShare, error) { + if len(X) != len(encShares) || len(encShares) != len(decShares) { + return nil, errorDifferentLengths + } + var D []*PubVerShare // good decrypted shares + for i := 0; i < len(X); i++ { + if err := VerifyDecShare(suite, G, X[i], encShares[i], decShares[i]); err == nil { + D = append(D, decShares[i]) + } + } + return D, nil +} + +// RecoverSecret first verifies the given decrypted shares against their +// decryption consistency proofs and then tries to recover the shared secret. +func RecoverSecret(suite Suite, G kyber.Point, X []kyber.Point, encShares []*PubVerShare, decShares []*PubVerShare, t int, n int) (kyber.Point, error) { + D, err := VerifyDecShareBatch(suite, G, X, encShares, decShares) + if err != nil { + return nil, err + } + if len(D) < t { + return nil, errorTooFewShares + } + var shares []*share.PubShare + for _, s := range D { + shares = append(shares, &s.S) + } + return share.RecoverCommit(suite, shares, t, n) +} diff --git a/kyber/share/pvss/pvss_test.go b/kyber/share/pvss/pvss_test.go new file mode 100644 index 0000000000..e9dfe32b5c --- /dev/null +++ b/kyber/share/pvss/pvss_test.go @@ -0,0 +1,258 @@ +package pvss + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" +) + +func TestPVSS(test *testing.T) { + suite := edwards25519.NewBlakeSHA256Ed25519() + G := suite.Point().Base() + H := suite.Point().Pick(suite.XOF([]byte("H"))) + n := 10 + t := 2*n/3 + 1 + x := make([]kyber.Scalar, n) // trustee private keys + X := make([]kyber.Point, n) // trustee public keys + for i := 0; i < n; i++ { + x[i] = suite.Scalar().Pick(suite.RandomStream()) + X[i] = suite.Point().Mul(x[i], nil) + } + + // Scalar of shared secret + secret := suite.Scalar().Pick(suite.RandomStream()) + + // (1) Share distribution (dealer) + encShares, pubPoly, err := EncShares(suite, H, X, secret, t) + require.Equal(test, err, nil) + + // (2) Share decryption (trustees) + sH := make([]kyber.Point, n) + for i := 0; i < n; i++ { + sH[i] = pubPoly.Eval(encShares[i].S.I).V + } + + var K []kyber.Point // good public keys + var E []*PubVerShare // good encrypted shares + var D []*PubVerShare // good decrypted shares + + for i := 0; i < n; i++ { + if ds, err := DecShare(suite, H, X[i], sH[i], x[i], encShares[i]); err == nil { + K = append(K, X[i]) + E = append(E, encShares[i]) + D = append(D, ds) + } + } + + // (3) Check decrypted shares and recover secret if possible (dealer/3rd party) + recovered, err := RecoverSecret(suite, G, K, E, D, t, n) + require.Equal(test, err, nil) + require.True(test, suite.Point().Mul(secret, nil).Equal(recovered)) +} + +func TestPVSSDelete(test *testing.T) { + suite := edwards25519.NewBlakeSHA256Ed25519() + G := suite.Point().Base() + H := suite.Point().Pick(suite.XOF([]byte("H"))) + n := 10 + t := 2*n/3 + 1 + x := make([]kyber.Scalar, n) // trustee private keys + X := make([]kyber.Point, n) // trustee public keys + for i := 0; i < n; i++ { + x[i] = suite.Scalar().Pick(suite.RandomStream()) + X[i] = suite.Point().Mul(x[i], nil) + } + + // Scalar of shared secret + secret := suite.Scalar().Pick(suite.RandomStream()) + + // (1) Share distribution (dealer) + encShares, pubPoly, err := EncShares(suite, H, X, secret, t) + require.Equal(test, err, nil) + + // Corrupt some of the encrypted shares + encShares[0].S.V = suite.Point().Null() + encShares[5].S.V = suite.Point().Null() + + // (2) Share decryption (trustees) + sH := make([]kyber.Point, n) + for i := 0; i < n; i++ { + sH[i] = pubPoly.Eval(encShares[i].S.I).V + } + + var K []kyber.Point // good public keys + var E []*PubVerShare // good encrypted shares + var D []*PubVerShare // good decrypted shares + + for i := 0; i < n; i++ { + if ds, err := DecShare(suite, H, X[i], sH[i], x[i], encShares[i]); err == nil { + K = append(K, X[i]) + E = append(E, encShares[i]) + D = append(D, ds) + } + } + + // Corrupt some of the decrypted shares + D[1].S.V = suite.Point().Null() + + // (3) Check decrypted shares and recover secret if possible (dealer/3rd party) + recovered, err := RecoverSecret(suite, G, K, E, D, t, n) + require.Equal(test, err, nil) + require.True(test, suite.Point().Mul(secret, nil).Equal(recovered)) +} + +func TestPVSSDeleteFail(test *testing.T) { + suite := edwards25519.NewBlakeSHA256Ed25519() + G := suite.Point().Base() + H := suite.Point().Pick(suite.XOF([]byte("H"))) + n := 10 + t := 2*n/3 + 1 + x := make([]kyber.Scalar, n) // trustee private keys + X := make([]kyber.Point, n) // trustee public keys + for i := 0; i < n; i++ { + x[i] = suite.Scalar().Pick(suite.RandomStream()) + X[i] = suite.Point().Mul(x[i], nil) + } + + // Scalar of shared secret + secret := suite.Scalar().Pick(suite.RandomStream()) + + // (1) Share distribution (dealer) + encShares, pubPoly, err := EncShares(suite, H, X, secret, t) + require.Equal(test, err, nil) + + // Corrupt some of the encrypted shares + encShares[0].S.V = suite.Point().Null() + encShares[5].S.V = suite.Point().Null() + + // (2) Share decryption (trustees) + sH := make([]kyber.Point, n) + for i := 0; i < n; i++ { + sH[i] = pubPoly.Eval(encShares[i].S.I).V + } + + var K []kyber.Point // good public keys + var E []*PubVerShare // good encrypted shares + var D []*PubVerShare // good decrypted shares + + for i := 0; i < n; i++ { + if ds, err := DecShare(suite, H, X[i], sH[i], x[i], encShares[i]); err == nil { + K = append(K, X[i]) + E = append(E, encShares[i]) + D = append(D, ds) + } + } + + // Corrupt enough decrypted shares to make the secret unrecoverable + D[0].S.V = suite.Point().Null() + D[1].S.V = suite.Point().Null() + + // (3) Check decrypted shares and recover secret if possible (dealer/3rd party) + _, err = RecoverSecret(suite, G, K, E, D, t, n) + require.Equal(test, err, errorTooFewShares) // this test is supposed to fail +} + +func TestPVSSBatch(test *testing.T) { + suite := edwards25519.NewBlakeSHA256Ed25519() + G := suite.Point().Base() + H := suite.Point().Pick(suite.XOF([]byte("H"))) + n := 5 + t := 2*n/3 + 1 + x := make([]kyber.Scalar, n) // trustee private keys + X := make([]kyber.Point, n) // trustee public keys + for i := 0; i < n; i++ { + x[i] = suite.Scalar().Pick(suite.RandomStream()) + X[i] = suite.Point().Mul(x[i], nil) + } + + // (1) Share distribution (multiple dealers) + s0 := suite.Scalar().Pick(suite.RandomStream()) + e0, p0, err := EncShares(suite, H, X, s0, t) + require.Equal(test, err, nil) + + s1 := suite.Scalar().Pick(suite.RandomStream()) + e1, p1, err := EncShares(suite, H, X, s1, t) + require.Equal(test, err, nil) + + s2 := suite.Scalar().Pick(suite.RandomStream()) + e2, p2, err := EncShares(suite, H, X, s2, t) + require.Equal(test, err, nil) + + sH0 := make([]kyber.Point, n) + sH1 := make([]kyber.Point, n) + sH2 := make([]kyber.Point, n) + for i := 0; i < n; i++ { + sH0[i] = p0.Eval(e0[i].S.I).V + sH1[i] = p1.Eval(e1[i].S.I).V + sH2[i] = p2.Eval(e2[i].S.I).V + } + + // Batch verification + X0, E0, err := VerifyEncShareBatch(suite, H, X, sH0, e0) + require.Equal(test, err, nil) + + X1, E1, err := VerifyEncShareBatch(suite, H, X, sH1, e1) + require.Equal(test, err, nil) + + X2, E2, err := VerifyEncShareBatch(suite, H, X, sH2, e2) + require.Equal(test, err, nil) + + // Reorder (some) poly evals, keys, and shares + P0 := []kyber.Point{p0.Eval(E0[0].S.I).V, p1.Eval(E1[0].S.I).V, p2.Eval(E2[0].S.I).V} + P1 := []kyber.Point{p0.Eval(E0[1].S.I).V, p1.Eval(E1[1].S.I).V, p2.Eval(E2[1].S.I).V} + P2 := []kyber.Point{p0.Eval(E0[2].S.I).V, p1.Eval(E1[2].S.I).V, p2.Eval(E2[2].S.I).V} + P3 := []kyber.Point{p0.Eval(E0[3].S.I).V, p1.Eval(E1[3].S.I).V, p2.Eval(E2[3].S.I).V} + + Y0 := []kyber.Point{X0[0], X1[0], X2[0]} + Y1 := []kyber.Point{X0[1], X1[1], X2[1]} + Y2 := []kyber.Point{X0[2], X1[2], X2[2]} + Y3 := []kyber.Point{X0[3], X1[3], X2[3]} + + Z0 := []*PubVerShare{E0[0], E1[0], E2[0]} + Z1 := []*PubVerShare{E0[1], E1[1], E2[1]} + Z2 := []*PubVerShare{E0[2], E1[2], E2[2]} + Z3 := []*PubVerShare{E0[3], E1[3], E2[3]} + + // (2) Share batch decryption (trustees) + KD0, ED0, DD0, err := DecShareBatch(suite, H, Y0, P0, x[0], Z0) + require.Equal(test, err, nil) + + KD1, ED1, DD1, err := DecShareBatch(suite, H, Y1, P1, x[1], Z1) + require.Equal(test, err, nil) + + KD2, ED2, DD2, err := DecShareBatch(suite, H, Y2, P2, x[2], Z2) + require.Equal(test, err, nil) + + KD3, ED3, DD3, err := DecShareBatch(suite, H, Y3, P3, x[3], Z3) + require.Equal(test, err, nil) + + // Re-establish order + XF0 := []kyber.Point{KD0[0], KD1[0], KD2[0], KD3[0]} + XF1 := []kyber.Point{KD0[1], KD1[1], KD2[1], KD3[1]} + XF2 := []kyber.Point{KD0[2], KD1[2], KD2[2], KD3[2]} + + EF0 := []*PubVerShare{ED0[0], ED1[0], ED2[0], ED3[0]} + EF1 := []*PubVerShare{ED0[1], ED1[1], ED2[1], ED3[1]} + EF2 := []*PubVerShare{ED0[2], ED1[2], ED2[2], ED3[2]} + + DF0 := []*PubVerShare{DD0[0], DD1[0], DD2[0], DD3[0]} + DF1 := []*PubVerShare{DD0[1], DD1[1], DD2[1], DD3[1]} + DF2 := []*PubVerShare{DD0[2], DD1[2], DD2[2], DD3[2]} + + // (3) Recover secrets + S0, err := RecoverSecret(suite, G, XF0, EF0, DF0, t, n) + require.Equal(test, err, nil) + + S1, err := RecoverSecret(suite, G, XF1, EF1, DF1, t, n) + require.Equal(test, err, nil) + + S2, err := RecoverSecret(suite, G, XF2, EF2, DF2, t, n) + require.Equal(test, err, nil) + + // Verify secrets + require.True(test, suite.Point().Mul(s0, nil).Equal(S0)) + require.True(test, suite.Point().Mul(s1, nil).Equal(S1)) + require.True(test, suite.Point().Mul(s2, nil).Equal(S2)) +} diff --git a/kyber/share/vss/pedersen/dh.go b/kyber/share/vss/pedersen/dh.go new file mode 100644 index 0000000000..c4e34ddcee --- /dev/null +++ b/kyber/share/vss/pedersen/dh.go @@ -0,0 +1,52 @@ +package vss + +import ( + "crypto/aes" + "crypto/cipher" + "hash" + + "go.dedis.ch/kyber/v3" + + "golang.org/x/crypto/hkdf" +) + +// dhExchange computes the shared key from a private key and a public key +func dhExchange(suite Suite, ownPrivate kyber.Scalar, remotePublic kyber.Point) kyber.Point { + sk := suite.Point() + sk.Mul(ownPrivate, remotePublic) + return sk +} + +var sharedKeyLength = 32 + +// newAEAD returns the AEAD cipher to be use to encrypt a share +func newAEAD(fn func() hash.Hash, preSharedKey kyber.Point, context []byte) (cipher.AEAD, error) { + preBuff, _ := preSharedKey.MarshalBinary() + reader := hkdf.New(fn, preBuff, nil, context) + + sharedKey := make([]byte, sharedKeyLength) + if _, err := reader.Read(sharedKey); err != nil { + return nil, err + } + block, err := aes.NewCipher(sharedKey) + if err != nil { + return nil, err + } + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + return gcm, nil +} + +// context returns the context slice to be used when encrypting a share +func context(suite Suite, dealer kyber.Point, verifiers []kyber.Point) []byte { + h := suite.Hash() + _, _ = h.Write([]byte("vss-dealer")) + _, _ = dealer.MarshalTo(h) + _, _ = h.Write([]byte("vss-verifiers")) + for _, v := range verifiers { + _, _ = v.MarshalTo(h) + } + return h.Sum(nil) +} diff --git a/kyber/share/vss/pedersen/vss.go b/kyber/share/vss/pedersen/vss.go new file mode 100644 index 0000000000..2e5d462abb --- /dev/null +++ b/kyber/share/vss/pedersen/vss.go @@ -0,0 +1,777 @@ +// Package vss implements the verifiable secret sharing scheme from +// "Non-Interactive and Information-Theoretic Secure Verifiable Secret Sharing" +// by Torben Pryds Pedersen. +// https://link.springer.com/content/pdf/10.1007/3-540-46766-1_9.pdf +package vss + +import ( + "bytes" + "crypto/cipher" + "encoding/binary" + "errors" + "fmt" + "reflect" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/share" + "go.dedis.ch/kyber/v3/sign/schnorr" + "go.dedis.ch/protobuf" +) + +// Suite defines the capabilities required by the vss package. +type Suite interface { + kyber.Group + kyber.HashFactory + kyber.XOFFactory + kyber.Random +} + +// Dealer encapsulates for creating and distributing the shares and for +// replying to any Responses. +type Dealer struct { + suite Suite + reader cipher.Stream + // long is the longterm key of the Dealer + long kyber.Scalar + pub kyber.Point + secret kyber.Scalar + secretCommits []kyber.Point + secretPoly *share.PriPoly + verifiers []kyber.Point + hkdfContext []byte + // threshold of shares that is needed to reconstruct the secret + t int + // sessionID is a unique identifier for the whole session of the scheme + sessionID []byte + // list of deals this Dealer has generated + deals []*Deal + *Aggregator +} + +// Deal encapsulates the verifiable secret share and is sent by the dealer to a verifier. +type Deal struct { + // Unique session identifier for this protocol run + SessionID []byte + // Private share generated by the dealer + SecShare *share.PriShare + // Threshold used for this secret sharing run + T uint32 + // Commitments are the coefficients used to verify the shares against + Commitments []kyber.Point +} + +// EncryptedDeal contains the deal in a encrypted form only decipherable by the +// correct recipient. The encryption is performed in a similar manner as what is +// done in TLS. The dealer generates a temporary key pair, signs it with its +// longterm secret key. +type EncryptedDeal struct { + // Ephemeral Diffie Hellman key + DHKey []byte + // Signature of the DH key by the longterm key of the dealer + Signature []byte + // Nonce used for the encryption + Nonce []byte + // AEAD encryption of the deal marshalled by protobuf + Cipher []byte +} + +// Response is sent by the verifiers to all participants and holds each +// individual validation or refusal of a Deal. +type Response struct { + // SessionID related to this run of the protocol + SessionID []byte + // Index of the verifier issuing this Response from the new set of nodes + Index uint32 + // false = NO APPROVAL == Complaint , true = APPROVAL + Status bool + // Signature over the whole packet + Signature []byte +} + +const ( + // StatusComplaint is a constant value meaning that a verifier issues + // a Complaint against its Dealer. + StatusComplaint bool = false + // StatusApproval is a constant value meaning that a verifier agrees with + // the share it received. + StatusApproval bool = true +) + +// Justification is a message that is broadcasted by the Dealer in response to +// a Complaint. It contains the original Complaint as well as the shares +// distributed to the complainer. +type Justification struct { + // SessionID related to the current run of the protocol + SessionID []byte + // Index of the verifier who issued the Complaint,i.e. index of this Deal + Index uint32 + // Deal in cleartext + Deal *Deal + // Signature over the whole packet + Signature []byte +} + +// NewDealer returns a Dealer capable of leading the secret sharing scheme. It +// does not have to be trusted by other Verifiers. The security parameter t is +// the number of shares required to reconstruct the secret. It is HIGHLY +// RECOMMENDED to use a threshold higher or equal than what the method +// MinimumT() returns, otherwise it breaks the security assumptions of the whole +// scheme. It returns an error if the t is less than or equal to 2. +func NewDealer(suite Suite, longterm, secret kyber.Scalar, verifiers []kyber.Point, t int) (*Dealer, error) { + d := &Dealer{ + suite: suite, + long: longterm, + secret: secret, + verifiers: verifiers, + } + if !validT(t, verifiers) { + return nil, fmt.Errorf("dealer: t %d invalid", t) + } + d.t = t + + f := share.NewPriPoly(d.suite, d.t, d.secret, suite.RandomStream()) + d.pub = d.suite.Point().Mul(d.long, nil) + + // Compute public polynomial coefficients + F := f.Commit(d.suite.Point().Base()) + _, d.secretCommits = F.Info() + + var err error + d.sessionID, err = sessionID(d.suite, d.pub, d.verifiers, d.secretCommits, d.t) + if err != nil { + return nil, err + } + + d.Aggregator = newAggregator(d.suite, d.pub, d.verifiers, d.secretCommits, d.t, d.sessionID) + // C = F + G + d.deals = make([]*Deal, len(d.verifiers)) + for i := range d.verifiers { + fi := f.Eval(i) + d.deals[i] = &Deal{ + SessionID: d.sessionID, + SecShare: fi, + Commitments: d.secretCommits, + T: uint32(d.t), + } + } + d.hkdfContext = context(suite, d.pub, verifiers) + d.secretPoly = f + return d, nil +} + +// PlaintextDeal returns the plaintext version of the deal destined for peer i. +// Use this only for testing. +func (d *Dealer) PlaintextDeal(i int) (*Deal, error) { + if i >= len(d.deals) { + return nil, errors.New("dealer: PlaintextDeal given wrong index") + } + return d.deals[i], nil +} + +// EncryptedDeal returns the encryption of the deal that must be given to the +// verifier at index i. +// The dealer first generates a temporary Diffie Hellman key, signs it using its +// longterm key, and computes the shared key depending on its longterm and +// ephemeral key and the verifier's public key. +// This shared key is then fed into a HKDF whose output is the key to a AEAD +// (AES256-GCM) scheme to encrypt the deal. +func (d *Dealer) EncryptedDeal(i int) (*EncryptedDeal, error) { + vPub, ok := findPub(d.verifiers, uint32(i)) + if !ok { + return nil, errors.New("dealer: wrong index to generate encrypted deal") + } + // gen ephemeral key + dhSecret := d.suite.Scalar().Pick(d.suite.RandomStream()) + dhPublic := d.suite.Point().Mul(dhSecret, nil) + // signs the public key + dhPublicBuff, _ := dhPublic.MarshalBinary() + signature, err := schnorr.Sign(d.suite, d.long, dhPublicBuff) + if err != nil { + return nil, err + } + // AES128-GCM + pre := dhExchange(d.suite, dhSecret, vPub) + gcm, err := newAEAD(d.suite.Hash, pre, d.hkdfContext) + if err != nil { + return nil, err + } + + nonce := make([]byte, gcm.NonceSize()) + dealBuff, err := protobuf.Encode(d.deals[i]) + if err != nil { + return nil, err + } + encrypted := gcm.Seal(nil, nonce, dealBuff, d.hkdfContext) + dhBytes, _ := dhPublic.MarshalBinary() + return &EncryptedDeal{ + DHKey: dhBytes, + Signature: signature, + Nonce: nonce, + Cipher: encrypted, + }, nil +} + +// EncryptedDeals calls `EncryptedDeal` for each index of the verifier and +// returns the list of encrypted deals. Each index in the returned slice +// corresponds to the index in the list of verifiers. +func (d *Dealer) EncryptedDeals() ([]*EncryptedDeal, error) { + deals := make([]*EncryptedDeal, len(d.verifiers)) + var err error + for i := range d.verifiers { + deals[i], err = d.EncryptedDeal(i) + if err != nil { + return nil, err + } + } + return deals, nil +} + +// ProcessResponse analyzes the given Response. If it's a valid complaint, then +// it returns a Justification. This Justification must be broadcasted to every +// participants. If it's an invalid complaint, it returns an error about the +// complaint. The verifiers will also ignore an invalid Complaint. +func (d *Dealer) ProcessResponse(r *Response) (*Justification, error) { + if err := d.verifyResponse(r); err != nil { + return nil, err + } + if r.Status == StatusApproval { + return nil, nil + } + + j := &Justification{ + SessionID: d.sessionID, + // index is guaranteed to be good because of d.verifyResponse before + Index: r.Index, + Deal: d.deals[int(r.Index)], + } + sig, err := schnorr.Sign(d.suite, d.long, j.Hash(d.suite)) + if err != nil { + return nil, err + } + j.Signature = sig + return j, nil +} + +// SecretCommit returns the commitment of the secret being shared by this +// dealer. This function is only to be called once the deal has enough approvals +// and is verified otherwise it returns nil. +func (d *Dealer) SecretCommit() kyber.Point { + if !d.EnoughApprovals() || !d.DealCertified() { + return nil + } + return d.suite.Point().Mul(d.secret, nil) +} + +// Commits returns the commitments of the coefficient of the secret polynomial +// the Dealer is sharing. +func (d *Dealer) Commits() []kyber.Point { + return d.secretCommits +} + +// Key returns the longterm key pair used by this Dealer. +func (d *Dealer) Key() (secret kyber.Scalar, public kyber.Point) { + return d.long, d.pub +} + +// SessionID returns the current sessionID generated by this dealer for this +// protocol run. +func (d *Dealer) SessionID() []byte { + return d.sessionID +} + +// SetTimeout marks the end of a round, invalidating any missing (or future) response +// for this DKG protocol round. The caller is expected to call this after a long timeout +// so each DKG node can still compute its share if enough Deals are valid. +func (d *Dealer) SetTimeout() { + d.Aggregator.cleanVerifiers() +} + +// PrivatePoly returns the private polynomial used to generate the deal. This +// private polynomial can be saved and then later on used to generate new +// shares. This information SHOULD STAY PRIVATE and thus MUST never be given +// to any third party. +func (d *Dealer) PrivatePoly() *share.PriPoly { + return d.secretPoly +} + +// Verifier receives a Deal from a Dealer, can reply with a Complaint, and can +// collaborate with other Verifiers to reconstruct a secret. +type Verifier struct { + suite Suite + longterm kyber.Scalar + pub kyber.Point + dealer kyber.Point + index int + verifiers []kyber.Point + hkdfContext []byte + *Aggregator +} + +// NewVerifier returns a Verifier out of: +// - its longterm secret key +// - the longterm dealer public key +// - the list of public key of verifiers. The list MUST include the public key of this Verifier also. +// The security parameter t of the secret sharing scheme is automatically set to +// a default safe value. If a different t value is required, it is possible to set +// it with `verifier.SetT()`. +func NewVerifier(suite Suite, longterm kyber.Scalar, dealerKey kyber.Point, + verifiers []kyber.Point) (*Verifier, error) { + + pub := suite.Point().Mul(longterm, nil) + var ok bool + var index int + for i, v := range verifiers { + if v.Equal(pub) { + ok = true + index = i + break + } + } + if !ok { + return nil, errors.New("vss: public key not found in the list of verifiers") + } + v := &Verifier{ + suite: suite, + longterm: longterm, + dealer: dealerKey, + verifiers: verifiers, + pub: pub, + index: index, + hkdfContext: context(suite, dealerKey, verifiers), + } + return v, nil +} + +// ProcessEncryptedDeal decrypt the deal received from the Dealer. +// If the deal is valid, i.e. the verifier can verify its shares +// against the public coefficients and the signature is valid, an approval +// response is returned and must be broadcasted to every participants +// including the dealer. +// If the deal itself is invalid, it returns a complaint response that must be +// broadcasted to every other participants including the dealer. +// If the deal has already been received, or the signature generation of the +// response failed, it returns an error without any responses. +func (v *Verifier) ProcessEncryptedDeal(e *EncryptedDeal) (*Response, error) { + d, err := v.decryptDeal(e) + if err != nil { + return nil, err + } + if d.SecShare.I != v.index { + return nil, errors.New("vss: verifier got wrong index from deal") + } + + t := int(d.T) + + sid, err := sessionID(v.suite, v.dealer, v.verifiers, d.Commitments, t) + if err != nil { + return nil, err + } + + if v.Aggregator == nil { + v.Aggregator = newAggregator(v.suite, v.dealer, v.verifiers, d.Commitments, t, d.SessionID) + } + + r := &Response{ + SessionID: sid, + Index: uint32(v.index), + Status: StatusApproval, + } + if err = v.VerifyDeal(d, true); err != nil { + r.Status = StatusComplaint + } + + if err == errDealAlreadyProcessed { + return nil, err + } + + if r.Signature, err = schnorr.Sign(v.suite, v.longterm, r.Hash(v.suite)); err != nil { + return nil, err + } + + if err = v.Aggregator.addResponse(r); err != nil { + return nil, err + } + return r, nil +} + +func (v *Verifier) decryptDeal(e *EncryptedDeal) (*Deal, error) { + // verify signature + if err := schnorr.Verify(v.suite, v.dealer, e.DHKey, e.Signature); err != nil { + return nil, err + } + + // compute shared key and AES526-GCM cipher + dhKey := v.suite.Point() + if err := dhKey.UnmarshalBinary(e.DHKey); err != nil { + return nil, err + } + pre := dhExchange(v.suite, v.longterm, dhKey) + gcm, err := newAEAD(v.suite.Hash, pre, v.hkdfContext) + if err != nil { + return nil, err + } + decrypted, err := gcm.Open(nil, e.Nonce, e.Cipher, v.hkdfContext) + if err != nil { + return nil, err + } + deal := &Deal{} + err = deal.decode(v.suite, decrypted) + return deal, err +} + +// ErrNoDealBeforeResponse is an error returned if a verifier receives a +// deal before having received any responses. For the moment, the caller must +// be sure to have dispatched a deal before. +var ErrNoDealBeforeResponse = errors.New("verifier: need to receive deal before response") + +// ProcessResponse analyzes the given response. If it's a valid complaint, the +// verifier should expect to see a Justification from the Dealer. It returns an +// error if it's not a valid response. +// Call `v.DealCertified()` to check if the whole protocol is finished. +func (v *Verifier) ProcessResponse(resp *Response) error { + if v.Aggregator == nil { + return ErrNoDealBeforeResponse + } + return v.Aggregator.verifyResponse(resp) +} + +// Commits returns the commitments of the coefficients of the polynomial +// contained in the Deal received. It is public information. The private +// information in the deal must be retrieved through Deal(). +func (v *Verifier) Commits() []kyber.Point { + return v.deal.Commitments +} + +// Deal returns the Deal that this verifier has received. It returns +// nil if the deal is not certified or there is not enough approvals. +func (v *Verifier) Deal() *Deal { + if !v.EnoughApprovals() || !v.DealCertified() { + return nil + } + return v.deal +} + +// ProcessJustification takes a DealerResponse and returns an error if +// something went wrong during the verification. If it is the case, that +// probably means the Dealer is acting maliciously. In order to be sure, call +// `v.EnoughApprovals()` and if true, `v.DealCertified()`. +func (v *Verifier) ProcessJustification(dr *Justification) error { + return v.Aggregator.verifyJustification(dr) +} + +// Key returns the longterm key pair this verifier is using during this protocol +// run. +func (v *Verifier) Key() (kyber.Scalar, kyber.Point) { + return v.longterm, v.pub +} + +// Index returns the index of the verifier in the list of participants used +// during this run of the protocol. +func (v *Verifier) Index() int { + return v.index +} + +// SessionID returns the session id generated by the Dealer. It returns +// an nil slice if the verifier has not received the Deal yet. +func (v *Verifier) SessionID() []byte { + return v.sid +} + +// RecoverSecret recovers the secret shared by a Dealer by gathering at least t +// Deals from the verifiers. It returns an error if there is not enough Deals or +// if all Deals don't have the same SessionID. +func RecoverSecret(suite Suite, deals []*Deal, n, t int) (kyber.Scalar, error) { + shares := make([]*share.PriShare, len(deals)) + for i, deal := range deals { + // all sids the same + if bytes.Equal(deal.SessionID, deals[0].SessionID) { + shares[i] = deal.SecShare + } else { + return nil, errors.New("vss: all deals need to have same session id") + } + } + return share.RecoverSecret(suite, shares, t, n) +} + +// SetTimeout marks the end of a round, invalidating any missing (or future) response +// for this DKG protocol round. The caller is expected to call this after a long timeout +// so each DKG node can still compute its share if enough Deals are valid. +func (v *Verifier) SetTimeout() { + v.Aggregator.cleanVerifiers() +} + +// UnsafeSetResponseDKG is an UNSAFE bypass method to allow DKG to use VSS +// that works on basis of approval only. +func (v *Verifier) UnsafeSetResponseDKG(idx uint32, approval bool) { + r := &Response{ + SessionID: v.Aggregator.sid, + Index: uint32(idx), + Status: approval, + } + + v.Aggregator.addResponse(r) +} + +// Aggregator is used to collect all deals, and responses for one protocol run. +// It brings common functionalities for both Dealer and Verifier structs. +type Aggregator struct { + suite Suite + dealer kyber.Point + verifiers []kyber.Point + commits []kyber.Point + + responses map[uint32]*Response + sid []byte + deal *Deal + t int + badDealer bool +} + +func newAggregator(suite Suite, dealer kyber.Point, verifiers, commitments []kyber.Point, t int, sid []byte) *Aggregator { + agg := &Aggregator{ + suite: suite, + dealer: dealer, + verifiers: verifiers, + commits: commitments, + t: t, + sid: sid, + responses: make(map[uint32]*Response), + } + return agg +} + +// NewEmptyAggregator returns a structure capable of storing Responses about a +// deal and check if the deal is certified or not. +func NewEmptyAggregator(suite Suite, verifiers []kyber.Point) *Aggregator { + return &Aggregator{ + suite: suite, + verifiers: verifiers, + responses: make(map[uint32]*Response), + } +} + +var errDealAlreadyProcessed = errors.New("vss: verifier already received a deal") + +// VerifyDeal analyzes the deal and returns an error if it's incorrect. If +// inclusion is true, it also returns an error if it is the second time this struct +// analyzes a Deal. +func (a *Aggregator) VerifyDeal(d *Deal, inclusion bool) error { + if a.deal != nil && inclusion { + return errDealAlreadyProcessed + + } + if a.deal == nil { + a.commits = d.Commitments + a.sid = d.SessionID + a.deal = d + } + + if !validT(int(d.T), a.verifiers) { + return errors.New("vss: invalid t received in Deal") + } + + if !bytes.Equal(a.sid, d.SessionID) { + return errors.New("vss: find different sessionIDs from Deal") + } + + fi := d.SecShare + if fi.I < 0 || fi.I >= len(a.verifiers) { + return errors.New("vss: index out of bounds in Deal") + } + // compute fi * G + fig := a.suite.Point().Base().Mul(fi.V, nil) + + commitPoly := share.NewPubPoly(a.suite, nil, d.Commitments) + + pubShare := commitPoly.Eval(fi.I) + if !fig.Equal(pubShare.V) { + return errors.New("vss: share does not verify against commitments in Deal") + } + return nil +} + +// cleanVerifiers checks the Aggregator's response array and creates a StatusComplaint +// response for all verifiers that did not respond to the Deal. +func (a *Aggregator) cleanVerifiers() { + for i := range a.verifiers { + if _, ok := a.responses[uint32(i)]; !ok { + a.responses[uint32(i)] = &Response{ + SessionID: a.sid, + Index: uint32(i), + Status: StatusComplaint, + } + } + } +} + +// ProcessResponse verifies the validity of the given response and stores it +// internall. It is the public version of verifyResponse created this way to +// allow higher-level package to use these functionalities. +func (a *Aggregator) ProcessResponse(r *Response) error { + return a.verifyResponse(r) +} + +func (a *Aggregator) verifyResponse(r *Response) error { + if a.sid != nil && !bytes.Equal(r.SessionID, a.sid) { + return errors.New("vss: receiving inconsistent sessionID in response") + } + + pub, ok := findPub(a.verifiers, r.Index) + if !ok { + return errors.New("vss: index out of bounds in response") + } + + if err := schnorr.Verify(a.suite, pub, r.Hash(a.suite), r.Signature); err != nil { + return err + } + + return a.addResponse(r) +} + +func (a *Aggregator) verifyJustification(j *Justification) error { + if _, ok := findPub(a.verifiers, j.Index); !ok { + return errors.New("vss: index out of bounds in justification") + } + r, ok := a.responses[j.Index] + if !ok { + return errors.New("vss: no complaints received for this justification") + } + if r.Status != StatusComplaint { + return errors.New("vss: justification received for an approval") + } + + if err := a.VerifyDeal(j.Deal, false); err != nil { + // if one response is bad, flag the dealer as malicious + a.badDealer = true + return err + } + r.Status = StatusApproval + return nil +} + +func (a *Aggregator) addResponse(r *Response) error { + if _, ok := findPub(a.verifiers, r.Index); !ok { + return errors.New("vss: index out of bounds in Complaint") + } + if _, ok := a.responses[r.Index]; ok { + return errors.New("vss: already existing response from same origin") + } + a.responses[r.Index] = r + return nil +} + +// EnoughApprovals returns true if enough verifiers have sent their approval for +// the deal they received. +func (a *Aggregator) EnoughApprovals() bool { + var app int + for _, r := range a.responses { + if r.Status == StatusApproval { + app++ + } + } + return app >= a.t +} + +// Responses returns the current mapping from indexes to Responses. +func (a *Aggregator) Responses() map[uint32]*Response { + return a.responses +} + +// DealCertified returns true if there has been less than t complaints, all +// Justifications were correct and if EnoughApprovals() returns true. +func (a *Aggregator) DealCertified() bool { + var verifiersUnstable int + + // XXX currently it can still happen that an Aggregator has not been set, + // because it did not receive any deals yet or responses. + if a == nil { + return false + } + + // Check either a StatusApproval or StatusComplaint for all known verifiers + // i.e. make sure all verifiers are either timed-out or OK. + for i := range a.verifiers { + if _, ok := a.responses[uint32(i)]; !ok { + verifiersUnstable++ + } + } + + tooMuchComplaints := verifiersUnstable > 0 || a.badDealer + return a.EnoughApprovals() && !tooMuchComplaints +} + +// MinimumT returns the minimum safe T that is proven to be secure with this +// protocol. It expects n, the total number of participants. +// WARNING: Setting a lower T could make +// the whole protocol insecure. Setting a higher T only makes it harder to +// reconstruct the secret. +func MinimumT(n int) int { + return (n + 1) / 2 +} + +func validT(t int, verifiers []kyber.Point) bool { + return t >= 2 && t <= len(verifiers) && int(uint32(t)) == t +} + +func deriveH(suite Suite, verifiers []kyber.Point) kyber.Point { + var b bytes.Buffer + for _, v := range verifiers { + _, _ = v.MarshalTo(&b) + } + base := suite.Point().Pick(suite.XOF(b.Bytes())) + return base +} + +func findPub(verifiers []kyber.Point, idx uint32) (kyber.Point, bool) { + iidx := int(idx) + if iidx >= len(verifiers) { + return nil, false + } + return verifiers[iidx], true +} + +func sessionID(suite Suite, dealer kyber.Point, verifiers, commitments []kyber.Point, t int) ([]byte, error) { + h := suite.Hash() + _, _ = dealer.MarshalTo(h) + + for _, v := range verifiers { + _, _ = v.MarshalTo(h) + } + + for _, c := range commitments { + _, _ = c.MarshalTo(h) + } + _ = binary.Write(h, binary.LittleEndian, uint32(t)) + + return h.Sum(nil), nil +} + +// Hash returns the Hash representation of the Response +func (r *Response) Hash(s Suite) []byte { + h := s.Hash() + _, _ = h.Write([]byte("response")) + _, _ = h.Write(r.SessionID) + _ = binary.Write(h, binary.LittleEndian, r.Index) + _ = binary.Write(h, binary.LittleEndian, r.Status) + return h.Sum(nil) +} + +func (d *Deal) decode(s Suite, buff []byte) error { + constructors := make(protobuf.Constructors) + var point kyber.Point + var secret kyber.Scalar + constructors[reflect.TypeOf(&point).Elem()] = func() interface{} { return s.Point() } + constructors[reflect.TypeOf(&secret).Elem()] = func() interface{} { return s.Scalar() } + return protobuf.DecodeWithConstructors(buff, d, constructors) +} + +// Hash returns the hash of a Justification. +func (j *Justification) Hash(s Suite) []byte { + h := s.Hash() + _, _ = h.Write([]byte("justification")) + _, _ = h.Write(j.SessionID) + _ = binary.Write(h, binary.LittleEndian, j.Index) + buff, _ := protobuf.Encode(j.Deal) + _, _ = h.Write(buff) + return h.Sum(nil) +} diff --git a/kyber/share/vss/pedersen/vss_test.go b/kyber/share/vss/pedersen/vss_test.go new file mode 100644 index 0000000000..42007f7b82 --- /dev/null +++ b/kyber/share/vss/pedersen/vss_test.go @@ -0,0 +1,640 @@ +package vss + +import ( + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/sign/schnorr" + "go.dedis.ch/kyber/v3/xof/blake2xb" + "go.dedis.ch/protobuf" +) + +var rng = blake2xb.New(nil) + +var suite = edwards25519.NewBlakeSHA256Ed25519WithRand(rng) + +var nbVerifiers = 7 + +var vssThreshold int + +var verifiersPub []kyber.Point +var verifiersSec []kyber.Scalar + +var dealerPub kyber.Point +var dealerSec kyber.Scalar + +var secret kyber.Scalar + +func init() { + verifiersSec, verifiersPub = genCommits(nbVerifiers) + dealerSec, dealerPub = genPair() + secret, _ = genPair() + vssThreshold = MinimumT(nbVerifiers) +} + +func TestVSSWhole(t *testing.T) { + dealer, verifiers := genAll() + + // 1. dispatch deal + resps := make([]*Response, nbVerifiers) + encDeals, err := dealer.EncryptedDeals() + require.Nil(t, err) + for i, d := range encDeals { + require.Equal(t, ErrNoDealBeforeResponse, verifiers[i].ProcessResponse(nil)) + resp, err := verifiers[i].ProcessEncryptedDeal(d) + require.Nil(t, err) + resps[i] = resp + } + + // 2. dispatch responses + for _, resp := range resps { + for i, v := range verifiers { + if resp.Index == uint32(i) { + continue + } + require.Nil(t, v.ProcessResponse(resp)) + } + // 2.1. check dealer (no justification here) + j, err := dealer.ProcessResponse(resp) + require.Nil(t, err) + require.Nil(t, j) + } + + // 3. check certified + for _, v := range verifiers { + require.True(t, v.DealCertified()) + } + + // 4. collect deals + deals := make([]*Deal, nbVerifiers) + for i, v := range verifiers { + deals[i] = v.Deal() + } + + // 5. recover + sec, err := RecoverSecret(suite, deals, nbVerifiers, MinimumT(nbVerifiers)) + assert.Nil(t, err) + require.NotNil(t, sec) + assert.Equal(t, dealer.secret.String(), sec.String()) + + priPoly := dealer.PrivatePoly() + priCoeffs := priPoly.Coefficients() + require.Equal(t, secret.String(), priCoeffs[0].String()) +} + +func TestVSSDealerNew(t *testing.T) { + goodT := MinimumT(nbVerifiers) + dealer, err := NewDealer(suite, dealerSec, secret, verifiersPub, goodT) + require.NoError(t, err) + require.NotNil(t, dealer.secretPoly) + + for _, badT := range []int{0, 1, -4} { + _, err = NewDealer(suite, dealerSec, secret, verifiersPub, badT) + assert.Error(t, err) + } + +} + +func TestVSSVerifierNew(t *testing.T) { + randIdx := rand.Int() % len(verifiersPub) + v, err := NewVerifier(suite, verifiersSec[randIdx], dealerPub, verifiersPub) + assert.NoError(t, err) + assert.Equal(t, randIdx, v.index) + + wrongKey := suite.Scalar().Pick(rng) + _, err = NewVerifier(suite, wrongKey, dealerPub, verifiersPub) + assert.Error(t, err) +} + +func TestVSSShare(t *testing.T) { + dealer, verifiers := genAll() + ver := verifiers[0] + deal, err := dealer.EncryptedDeal(0) + require.Nil(t, err) + + resp, err := ver.ProcessEncryptedDeal(deal) + require.NotNil(t, resp) + require.Equal(t, StatusApproval, resp.Status) + require.Nil(t, err) + + aggr := ver.Aggregator + + for i := 1; i < aggr.t-1; i++ { + aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + } + // not enough approvals + assert.Nil(t, ver.Deal()) + + aggr.responses[uint32(aggr.t)] = &Response{Status: StatusApproval} + + // Timeout all other (i>t) verifiers + ver.SetTimeout() + + // deal not certified + aggr.badDealer = true + assert.Nil(t, ver.Deal()) + aggr.badDealer = false + + assert.NotNil(t, ver.Deal()) + +} + +func TestVSSAggregatorEnoughApprovals(t *testing.T) { + dealer := genDealer() + aggr := dealer.Aggregator + // just below + for i := 0; i < aggr.t-1; i++ { + aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + } + assert.False(t, aggr.EnoughApprovals()) + assert.Nil(t, dealer.SecretCommit()) + + aggr.responses[uint32(aggr.t)] = &Response{Status: StatusApproval} + assert.True(t, aggr.EnoughApprovals()) + + for i := aggr.t + 1; i < nbVerifiers; i++ { + aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + } + + // mark remaning verifiers as timed out + dealer.SetTimeout() + + assert.True(t, aggr.EnoughApprovals()) + assert.Equal(t, suite.Point().Mul(secret, nil), dealer.SecretCommit()) +} + +func TestVSSAggregatorDealCertified(t *testing.T) { + dealer := genDealer() + aggr := dealer.Aggregator + + for i := 0; i < aggr.t; i++ { + aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + } + + // Mark remaining verifiers as timed-out + dealer.SetTimeout() + + assert.True(t, aggr.DealCertified()) + assert.Equal(t, suite.Point().Mul(secret, nil), dealer.SecretCommit()) + // bad dealer response + aggr.badDealer = true + assert.False(t, aggr.DealCertified()) + assert.Nil(t, dealer.SecretCommit()) + + // reset dealer status + aggr.badDealer = false + + // inconsistent state on purpose + // too much complaints + for i := 0; i < aggr.t; i++ { + aggr.responses[uint32(i)] = &Response{Status: StatusComplaint} + } + assert.False(t, aggr.DealCertified()) +} + +func TestVSSVerifierDecryptDeal(t *testing.T) { + dealer, verifiers := genAll() + v := verifiers[0] + d := dealer.deals[0] + + // all fine + encD, err := dealer.EncryptedDeal(0) + require.Nil(t, err) + decD, err := v.decryptDeal(encD) + require.Nil(t, err) + b1, _ := protobuf.Encode(d) + b2, _ := protobuf.Encode(decD) + assert.Equal(t, b1, b2) + + // wrong dh key + goodDh := encD.DHKey + encD.DHKey, err = suite.Point().Null().MarshalBinary() + require.Nil(t, err) + decD, err = v.decryptDeal(encD) + assert.Error(t, err) + assert.Nil(t, decD) + encD.DHKey = goodDh + + // wrong signature + goodSig := encD.Signature + encD.Signature = randomBytes(32) + decD, err = v.decryptDeal(encD) + assert.Error(t, err) + assert.Nil(t, decD) + encD.Signature = goodSig + + // wrong ciphertext + goodCipher := encD.Cipher + encD.Cipher = randomBytes(len(goodCipher)) + decD, err = v.decryptDeal(encD) + assert.Error(t, err) + assert.Nil(t, decD) + encD.Cipher = goodCipher +} + +func TestVSSVerifierReceiveDeal(t *testing.T) { + dealer, verifiers := genAll() + v := verifiers[0] + d := dealer.deals[0] + + encD, err := dealer.EncryptedDeal(0) + require.Nil(t, err) + + // correct deal + resp, err := v.ProcessEncryptedDeal(encD) + require.NotNil(t, resp) + assert.Equal(t, StatusApproval, resp.Status) + assert.Nil(t, err) + assert.Equal(t, v.index, int(resp.Index)) + assert.Equal(t, dealer.sid, resp.SessionID) + assert.Nil(t, schnorr.Verify(suite, v.pub, resp.Hash(suite), resp.Signature)) + assert.Equal(t, v.responses[uint32(v.index)], resp) + + // wrong encryption + goodSig := encD.Signature + encD.Signature = randomBytes(32) + resp, err = v.ProcessEncryptedDeal(encD) + assert.Nil(t, resp) + assert.Error(t, err) + encD.Signature = goodSig + + // wrong index + goodIdx := d.SecShare.I + d.SecShare.I = (goodIdx - 1) % nbVerifiers + encD, _ = dealer.EncryptedDeal(0) + resp, err = v.ProcessEncryptedDeal(encD) + assert.Error(t, err) + assert.Nil(t, resp) + d.SecShare.I = goodIdx + + // wrong commitments + goodCommit := d.Commitments[0] + d.Commitments[0] = suite.Point().Pick(rng) + encD, _ = dealer.EncryptedDeal(0) + resp, err = v.ProcessEncryptedDeal(encD) + assert.Error(t, err) + assert.Nil(t, resp) + d.Commitments[0] = goodCommit + + // already seen twice + resp, err = v.ProcessEncryptedDeal(encD) + assert.Nil(t, resp) + assert.Error(t, err) + v.Aggregator.deal = nil + + // approval already existing from same origin, should never happen right ? + v.Aggregator.responses[uint32(v.index)] = &Response{Status: StatusApproval} + d.Commitments[0] = suite.Point().Pick(rng) + resp, err = v.ProcessEncryptedDeal(encD) + assert.Nil(t, resp) + assert.Error(t, err) + d.Commitments[0] = goodCommit + + // valid complaint + v.Aggregator.deal = nil + delete(v.Aggregator.responses, uint32(v.index)) + //d.RndShare.V = suite.Scalar().SetBytes(randomBytes(32)) + resp, err = v.ProcessEncryptedDeal(encD) + assert.NotNil(t, resp) + assert.Equal(t, StatusComplaint, resp.Status) + assert.Nil(t, err) +} + +func TestVSSAggregatorVerifyJustification(t *testing.T) { + dealer, verifiers := genAll() + v := verifiers[0] + d := dealer.deals[0] + + wrongV := suite.Scalar().Pick(rng) + goodV := d.SecShare.V + d.SecShare.V = wrongV + encD, _ := dealer.EncryptedDeal(0) + resp, err := v.ProcessEncryptedDeal(encD) + assert.NotNil(t, resp) + assert.Equal(t, StatusComplaint, resp.Status) + assert.Nil(t, err) + assert.Equal(t, v.responses[uint32(v.index)], resp) + // in tests, pointers point to the same underlying share.. + d.SecShare.V = goodV + + j, err := dealer.ProcessResponse(resp) + + // invalid deal justified + goodV = j.Deal.SecShare.V + j.Deal.SecShare.V = wrongV + err = v.ProcessJustification(j) + assert.Error(t, err) + assert.True(t, v.Aggregator.badDealer) + j.Deal.SecShare.V = goodV + v.Aggregator.badDealer = false + + // valid complaint + assert.Nil(t, v.ProcessJustification(j)) + + // invalid complaint + resp.SessionID = randomBytes(len(resp.SessionID)) + badJ, err := dealer.ProcessResponse(resp) + assert.Nil(t, badJ) + assert.Error(t, err) + resp.SessionID = dealer.sid + + // no complaints for this justification before + delete(v.Aggregator.responses, uint32(v.index)) + assert.Error(t, v.ProcessJustification(j)) + v.Aggregator.responses[uint32(v.index)] = resp + +} + +func TestVSSAggregatorVerifyResponseDuplicate(t *testing.T) { + dealer, verifiers := genAll() + v1 := verifiers[0] + v2 := verifiers[1] + //d1 := dealer.deals[0] + //d2 := dealer.deals[1] + encD1, _ := dealer.EncryptedDeal(0) + encD2, _ := dealer.EncryptedDeal(1) + + resp1, err := v1.ProcessEncryptedDeal(encD1) + assert.Nil(t, err) + assert.NotNil(t, resp1) + assert.Equal(t, StatusApproval, resp1.Status) + + resp2, err := v2.ProcessEncryptedDeal(encD2) + assert.Nil(t, err) + assert.NotNil(t, resp2) + assert.Equal(t, StatusApproval, resp2.Status) + + err = v1.ProcessResponse(resp2) + assert.Nil(t, err) + r, ok := v1.Aggregator.responses[uint32(v2.index)] + assert.True(t, ok) + assert.Equal(t, resp2, r) + + err = v1.ProcessResponse(resp2) + assert.Error(t, err) + + delete(v1.Aggregator.responses, uint32(v2.index)) + v1.Aggregator.responses[uint32(v2.index)] = &Response{Status: StatusApproval} + err = v1.ProcessResponse(resp2) + assert.Error(t, err) +} + +func TestVSSAggregatorVerifyResponse(t *testing.T) { + dealer, verifiers := genAll() + v := verifiers[0] + deal := dealer.deals[0] + //goodSec := deal.SecShare.V + wrongSec, _ := genPair() + deal.SecShare.V = wrongSec + encD, _ := dealer.EncryptedDeal(0) + // valid complaint + resp, err := v.ProcessEncryptedDeal(encD) + assert.Nil(t, err) + assert.NotNil(t, resp) + assert.Equal(t, StatusComplaint, resp.Status) + assert.NotNil(t, v.Aggregator) + assert.Equal(t, resp.SessionID, dealer.sid) + + aggr := v.Aggregator + r, ok := aggr.responses[uint32(v.index)] + assert.True(t, ok) + assert.Equal(t, StatusComplaint, r.Status) + + // wrong index + resp.Index = uint32(len(verifiersPub)) + sig, err := schnorr.Sign(suite, v.longterm, resp.Hash(suite)) + resp.Signature = sig + assert.Error(t, aggr.verifyResponse(resp)) + resp.Index = 0 + + // wrong signature + goodSig := resp.Signature + resp.Signature = randomBytes(len(goodSig)) + assert.Error(t, aggr.verifyResponse(resp)) + resp.Signature = goodSig + + // wrongID + wrongID := randomBytes(len(resp.SessionID)) + goodID := resp.SessionID + resp.SessionID = wrongID + assert.Error(t, aggr.verifyResponse(resp)) + resp.SessionID = goodID +} + +func TestVSSAggregatorAllResponses(t *testing.T) { + dealer := genDealer() + aggr := dealer.Aggregator + + for i := 0; i < aggr.t; i++ { + aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + } + assert.True(t, aggr.EnoughApprovals()) + assert.False(t, aggr.DealCertified()) + + for i := aggr.t; i < nbVerifiers; i++ { + aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + } + + assert.True(t, aggr.DealCertified()) + assert.Equal(t, suite.Point().Mul(secret, nil), dealer.SecretCommit()) +} + +func TestVSSDealerTimeout(t *testing.T) { + dealer := genDealer() + aggr := dealer.Aggregator + + for i := 0; i < aggr.t; i++ { + aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + } + + // Enough approvals, but all remaining responses missing + assert.True(t, aggr.EnoughApprovals()) + assert.False(t, aggr.DealCertified()) + + // Tell dealer to consider other verifiers timed-out + dealer.SetTimeout() + + // Deal should be certified + assert.True(t, aggr.DealCertified()) + assert.NotNil(t, dealer.SecretCommit()) +} + +func TestVSSVerifierTimeout(t *testing.T) { + dealer, verifiers := genAll() + v := verifiers[0] + + encDeal, err := dealer.EncryptedDeal(0) + + require.Nil(t, err) + + // Make verifier create it's Aggregator by processing EncDeal + resp, err := v.ProcessEncryptedDeal(encDeal) + require.NotNil(t, resp) + require.Nil(t, err) + + aggr := v.Aggregator + + // Add t responses + for i := 0; i < aggr.t; i++ { + aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + } + + // Enough Approvals, but not a response for every verifier + assert.True(t, aggr.EnoughApprovals()) + assert.False(t, aggr.DealCertified()) + + // Trigger time out, thus adding StatusComplaint to all + // remaining verifiers + v.SetTimeout() + + // Deal must be certified now + assert.True(t, aggr.DealCertified()) + assert.NotNil(t, v.Deal()) +} + +func TestVSSAggregatorVerifyDeal(t *testing.T) { + dealer := genDealer() + aggr := dealer.Aggregator + deals := dealer.deals + + // OK + deal := deals[0] + err := aggr.VerifyDeal(deal, true) + assert.NoError(t, err) + assert.NotNil(t, aggr.deal) + + // already received deal + err = aggr.VerifyDeal(deal, true) + assert.Error(t, err) + + // wrong T + wrongT := uint32(1) + goodT := deal.T + deal.T = wrongT + assert.Error(t, aggr.VerifyDeal(deal, false)) + deal.T = goodT + + // wrong SessionID + goodSid := deal.SessionID + deal.SessionID = make([]byte, 32) + assert.Error(t, aggr.VerifyDeal(deal, false)) + deal.SessionID = goodSid + + // index different in one share + goodI := deal.SecShare.I + deal.SecShare.I = goodI + 1 + assert.Error(t, aggr.VerifyDeal(deal, false)) + deal.SecShare.I = goodI + + // index not in bounds + deal.SecShare.I = -1 + assert.Error(t, aggr.VerifyDeal(deal, false)) + deal.SecShare.I = len(verifiersPub) + assert.Error(t, aggr.VerifyDeal(deal, false)) + + // shares invalid in respect to the commitments + wrongSec, _ := genPair() + deal.SecShare.V = wrongSec + assert.Error(t, aggr.VerifyDeal(deal, false)) +} + +func TestVSSAggregatorAddComplaint(t *testing.T) { + dealer := genDealer() + aggr := dealer.Aggregator + + var idx uint32 = 1 + c := &Response{ + Index: idx, + Status: StatusComplaint, + } + // ok + assert.Nil(t, aggr.addResponse(c)) + assert.Equal(t, aggr.responses[idx], c) + + // response already there + assert.Error(t, aggr.addResponse(c)) + delete(aggr.responses, idx) + +} + +func TestVSSSessionID(t *testing.T) { + dealer, _ := NewDealer(suite, dealerSec, secret, verifiersPub, vssThreshold) + commitments := dealer.deals[0].Commitments + sid, err := sessionID(suite, dealerPub, verifiersPub, commitments, dealer.t) + assert.NoError(t, err) + + sid2, err2 := sessionID(suite, dealerPub, verifiersPub, commitments, dealer.t) + assert.NoError(t, err2) + assert.Equal(t, sid, sid2) + + wrongDealerPub := suite.Point().Add(dealerPub, dealerPub) + + sid3, err3 := sessionID(suite, wrongDealerPub, verifiersPub, commitments, dealer.t) + assert.NoError(t, err3) + assert.NotEqual(t, sid3, sid2) +} + +func TestVSSFindPub(t *testing.T) { + p, ok := findPub(verifiersPub, 0) + assert.True(t, ok) + assert.Equal(t, verifiersPub[0], p) + + p, ok = findPub(verifiersPub, uint32(len(verifiersPub))) + assert.False(t, ok) + assert.Nil(t, p) +} + +func TestVSSDHExchange(t *testing.T) { + pub := suite.Point().Base() + priv := suite.Scalar().Pick(rng) + point := dhExchange(suite, priv, pub) + assert.Equal(t, pub.Mul(priv, nil).String(), point.String()) +} + +func TestVSSContext(t *testing.T) { + c := context(suite, dealerPub, verifiersPub) + assert.Len(t, c, suite.Hash().Size()) +} + +func genPair() (kyber.Scalar, kyber.Point) { + secret := suite.Scalar().Pick(suite.RandomStream()) + public := suite.Point().Mul(secret, nil) + return secret, public +} + +func genCommits(n int) ([]kyber.Scalar, []kyber.Point) { + var secrets = make([]kyber.Scalar, n) + var publics = make([]kyber.Point, n) + for i := 0; i < n; i++ { + secrets[i], publics[i] = genPair() + } + return secrets, publics +} + +func genDealer() *Dealer { + d, _ := NewDealer(suite, dealerSec, secret, verifiersPub, vssThreshold) + return d +} + +func genAll() (*Dealer, []*Verifier) { + dealer := genDealer() + var verifiers = make([]*Verifier, nbVerifiers) + for i := 0; i < nbVerifiers; i++ { + v, _ := NewVerifier(suite, verifiersSec[i], dealerPub, verifiersPub) + verifiers[i] = v + } + return dealer, verifiers +} + +func randomBytes(n int) []byte { + var buff = make([]byte, n) + _, err := rand.Read(buff) + if err != nil { + panic(err) + } + return buff +} diff --git a/kyber/share/vss/rabin/dh.go b/kyber/share/vss/rabin/dh.go new file mode 100644 index 0000000000..345c397d19 --- /dev/null +++ b/kyber/share/vss/rabin/dh.go @@ -0,0 +1,56 @@ +package vss + +import ( + "crypto/aes" + "crypto/cipher" + "hash" + + "go.dedis.ch/kyber/v3" + + "golang.org/x/crypto/hkdf" +) + +// dhExchange computes the shared key from a private key and a public key +func dhExchange(suite Suite, ownPrivate kyber.Scalar, remotePublic kyber.Point) kyber.Point { + sk := suite.Point() + sk.Mul(ownPrivate, remotePublic) + return sk +} + +var sharedKeyLength = 32 + +// newAEAD returns the AEAD cipher to be use to encrypt a share +func newAEAD(fn func() hash.Hash, preSharedKey kyber.Point, context []byte) (cipher.AEAD, error) { + preBuff, _ := preSharedKey.MarshalBinary() + reader := hkdf.New(fn, preBuff, nil, context) + + sharedKey := make([]byte, sharedKeyLength) + if _, err := reader.Read(sharedKey); err != nil { + return nil, err + } + block, err := aes.NewCipher(sharedKey) + if err != nil { + return nil, err + } + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + return gcm, nil +} + +// keySize is arbitrary, make it long enough to seed the XOF +const keySize = 128 + +// context returns the context slice to be used when encrypting a share +func context(suite Suite, dealer kyber.Point, verifiers []kyber.Point) []byte { + h := suite.XOF([]byte("vss-dealer")) + _, _ = dealer.MarshalTo(h) + _, _ = h.Write([]byte("vss-verifiers")) + for _, v := range verifiers { + _, _ = v.MarshalTo(h) + } + sum := make([]byte, keySize) + h.Read(sum) + return sum +} diff --git a/kyber/share/vss/rabin/vss.go b/kyber/share/vss/rabin/vss.go new file mode 100644 index 0000000000..d9e8f06e9e --- /dev/null +++ b/kyber/share/vss/rabin/vss.go @@ -0,0 +1,765 @@ +// Package vss implements the verifiable secret sharing scheme from the +// paper "Provably Secure Distributed Schnorr Signatures and a (t, n) Threshold +// Scheme for Implicit Certificates". +// VSS enables a dealer to share a secret securely and verifiably among n +// participants out of which at least t are required for its reconstruction. +// The verifiability of the process prevents a +// malicious dealer from influencing the outcome to his advantage as each +// verifier can check the validity of the received share. The protocol has the +// following steps: +// +// 1) The dealer send a Deal to every verifiers using `Deals()`. Each deal must +// be sent securely to one verifier whose public key is at the same index than +// the index of the Deal. +// +// 2) Each verifier processes the Deal with `ProcessDeal`. +// This function returns a Response which can be twofold: +// - an approval, to confirm a correct deal +// - a complaint to announce an incorrect deal notifying others that the +// dealer might be malicious. +// All Responses must be broadcasted to every verifiers and the dealer. +// 3) The dealer can respond to each complaint by a justification revealing the +// share he originally sent out to the accusing verifier. This is done by +// calling `ProcessResponse` on the `Dealer`. +// 4) The verifiers refuse the shared secret and abort the protocol if there +// are at least t complaints OR if a Justification is wrong. The verifiers +// accept the shared secret if there are at least t approvals at which point +// any t out of n verifiers can reveal their shares to reconstruct the shared +// secret. +package vss + +import ( + "bytes" + "crypto/cipher" + "encoding/binary" + "errors" + "fmt" + "reflect" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/share" + "go.dedis.ch/kyber/v3/sign/schnorr" + "go.dedis.ch/protobuf" +) + +// Suite defines the capabilities required by the vss package. +type Suite interface { + kyber.Group + kyber.HashFactory + kyber.XOFFactory + kyber.Random +} + +// Dealer encapsulates for creating and distributing the shares and for +// replying to any Responses. +type Dealer struct { + suite Suite + reader cipher.Stream + // long is the longterm key of the Dealer + long kyber.Scalar + pub kyber.Point + secret kyber.Scalar + secretCommits []kyber.Point + verifiers []kyber.Point + hkdfContext []byte + // threshold of shares that is needed to reconstruct the secret + t int + // sessionID is a unique identifier for the whole session of the scheme + sessionID []byte + // list of deals this Dealer has generated + deals []*Deal + *aggregator +} + +// Deal encapsulates the verifiable secret share and is sent by the dealer to a verifier. +type Deal struct { + // Unique session identifier for this protocol run + SessionID []byte + // Private share generated by the dealer + SecShare *share.PriShare + // Random share generated by the dealer + RndShare *share.PriShare + // Threshold used for this secret sharing run + T uint32 + // Commitments are the coefficients used to verify the shares against + Commitments []kyber.Point +} + +// EncryptedDeal contains the deal in a encrypted form only decipherable by the +// correct recipient. The encryption is performed in a similar manner as what is +// done in TLS. The dealer generates a temporary key pair, signs it with its +// longterm secret key. +type EncryptedDeal struct { + // Ephemeral Diffie Hellman key + DHKey kyber.Point + // Signature of the DH key by the longterm key of the dealer + Signature []byte + // Nonce used for the encryption + Nonce []byte + // AEAD encryption of the deal marshalled by protobuf + Cipher []byte +} + +// Response is sent by the verifiers to all participants and holds each +// individual validation or refusal of a Deal. +type Response struct { + // SessionID related to this run of the protocol + SessionID []byte + // Index of the verifier issuing this Response + Index uint32 + // Approved is true if the Response is valid + Approved bool + // Signature over the whole packet + Signature []byte +} + +// Justification is a message that is broadcasted by the Dealer in response to +// a Complaint. It contains the original Complaint as well as the shares +// distributed to the complainer. +type Justification struct { + // SessionID related to the current run of the protocol + SessionID []byte + // Index of the verifier who issued the Complaint,i.e. index of this Deal + Index uint32 + // Deal in cleartext + Deal *Deal + // Signature over the whole packet + Signature []byte +} + +// NewDealer returns a Dealer capable of leading the secret sharing scheme. It +// does not have to be trusted by other Verifiers. The security parameter t is +// the number of shares required to reconstruct the secret. It is HIGHLY +// RECOMMENDED to use a threshold higher or equal than what the method +// MinimumT() returns, otherwise it breaks the security assumptions of the whole +// scheme. It returns an error if the t is inferior or equal to 2. +func NewDealer(suite Suite, longterm, secret kyber.Scalar, verifiers []kyber.Point, t int) (*Dealer, error) { + d := &Dealer{ + suite: suite, + long: longterm, + secret: secret, + verifiers: verifiers, + } + if !validT(t, verifiers) { + return nil, fmt.Errorf("dealer: t %d invalid", t) + } + d.t = t + + H := deriveH(d.suite, d.verifiers) + f := share.NewPriPoly(d.suite, d.t, d.secret, suite.RandomStream()) + g := share.NewPriPoly(d.suite, d.t, nil, suite.RandomStream()) + d.pub = d.suite.Point().Mul(d.long, nil) + + // Compute public polynomial coefficients + F := f.Commit(d.suite.Point().Base()) + _, d.secretCommits = F.Info() + G := g.Commit(H) + + C, err := F.Add(G) + if err != nil { + return nil, err + } + _, commitments := C.Info() + + d.sessionID, err = sessionID(d.suite, d.pub, d.verifiers, commitments, d.t) + if err != nil { + return nil, err + } + + d.aggregator = newAggregator(d.suite, d.pub, d.verifiers, commitments, d.t, d.sessionID) + // C = F + G + d.deals = make([]*Deal, len(d.verifiers)) + for i := range d.verifiers { + fi := f.Eval(i) + gi := g.Eval(i) + d.deals[i] = &Deal{ + SessionID: d.sessionID, + SecShare: fi, + RndShare: gi, + Commitments: commitments, + T: uint32(d.t), + } + } + d.hkdfContext = context(suite, d.pub, verifiers) + return d, nil +} + +// PlaintextDeal returns the plaintext version of the deal destined for peer i. +// Use this only for testing. +func (d *Dealer) PlaintextDeal(i int) (*Deal, error) { + if i >= len(d.deals) { + return nil, errors.New("dealer: PlaintextDeal given wrong index") + } + return d.deals[i], nil +} + +// EncryptedDeal returns the encryption of the deal that must be given to the +// verifier at index i. +// The dealer first generates a temporary Diffie Hellman key, signs it using its +// longterm key, and computes the shared key depending on its longterm and +// ephemeral key and the verifier's public key. +// This shared key is then fed into a HKDF whose output is the key to a AEAD +// (AES256-GCM) scheme to encrypt the deal. +func (d *Dealer) EncryptedDeal(i int) (*EncryptedDeal, error) { + vPub, ok := findPub(d.verifiers, uint32(i)) + if !ok { + return nil, errors.New("dealer: wrong index to generate encrypted deal") + } + // gen ephemeral key + dhSecret := d.suite.Scalar().Pick(d.suite.RandomStream()) + dhPublic := d.suite.Point().Mul(dhSecret, nil) + // signs the public key + dhPublicBuff, _ := dhPublic.MarshalBinary() + signature, err := schnorr.Sign(d.suite, d.long, dhPublicBuff) + if err != nil { + return nil, err + } + // AES128-GCM + pre := dhExchange(d.suite, dhSecret, vPub) + gcm, err := newAEAD(d.suite.Hash, pre, d.hkdfContext) + if err != nil { + return nil, err + } + + nonce := make([]byte, gcm.NonceSize()) + dealBuff, err := protobuf.Encode(d.deals[i]) + if err != nil { + return nil, err + } + encrypted := gcm.Seal(nil, nonce, dealBuff, d.hkdfContext) + return &EncryptedDeal{ + DHKey: dhPublic, + Signature: signature, + Nonce: nonce, + Cipher: encrypted, + }, nil +} + +// EncryptedDeals calls `EncryptedDeal` for each index of the verifier and +// returns the list of encrypted deals. Each index in the returned slice +// corresponds to the index in the list of verifiers. +func (d *Dealer) EncryptedDeals() ([]*EncryptedDeal, error) { + deals := make([]*EncryptedDeal, len(d.verifiers)) + var err error + for i := range d.verifiers { + deals[i], err = d.EncryptedDeal(i) + if err != nil { + return nil, err + } + } + return deals, nil +} + +// ProcessResponse analyzes the given Response. If it's a valid complaint, then +// it returns a Justification. This Justification must be broadcasted to every +// participants. If it's an invalid complaint, it returns an error about the +// complaint. The verifiers will also ignore an invalid Complaint. +func (d *Dealer) ProcessResponse(r *Response) (*Justification, error) { + if err := d.verifyResponse(r); err != nil { + return nil, err + } + if r.Approved { + return nil, nil + } + + j := &Justification{ + SessionID: d.sessionID, + // index is guaranteed to be good because of d.verifyResponse before + Index: r.Index, + Deal: d.deals[int(r.Index)], + } + sig, err := schnorr.Sign(d.suite, d.long, j.Hash(d.suite)) + if err != nil { + return nil, err + } + j.Signature = sig + return j, nil +} + +// SecretCommit returns the commitment of the secret being shared by this +// dealer. This function is only to be called once the deal has enough approvals +// and is verified otherwise it returns nil. +func (d *Dealer) SecretCommit() kyber.Point { + if !d.EnoughApprovals() || !d.DealCertified() { + return nil + } + return d.suite.Point().Mul(d.secret, nil) +} + +// Commits returns the commitments of the coefficient of the secret polynomial +// the Dealer is sharing. +func (d *Dealer) Commits() []kyber.Point { + if !d.EnoughApprovals() || !d.DealCertified() { + return nil + } + return d.secretCommits +} + +// Key returns the longterm key pair used by this Dealer. +func (d *Dealer) Key() (secret kyber.Scalar, public kyber.Point) { + return d.long, d.pub +} + +// SessionID returns the current sessionID generated by this dealer for this +// protocol run. +func (d *Dealer) SessionID() []byte { + return d.sessionID +} + +// SetTimeout tells this dealer to consider this moment the maximum time limit. +// it calls cleanVerifiers which will take care of all Verifiers who have not +// responded until now. +func (d *Dealer) SetTimeout() { + d.aggregator.cleanVerifiers() +} + +// Verifier receives a Deal from a Dealer, can reply with a Complaint, and can +// collaborate with other Verifiers to reconstruct a secret. +type Verifier struct { + suite Suite + longterm kyber.Scalar + pub kyber.Point + dealer kyber.Point + index int + verifiers []kyber.Point + hkdfContext []byte + *aggregator +} + +// NewVerifier returns a Verifier out of: +// - its longterm secret key +// - the longterm dealer public key +// - the list of public key of verifiers. The list MUST include the public key +// of this Verifier also. +// The security parameter t of the secret sharing scheme is automatically set to +// a default safe value. If a different t value is required, it is possible to set +// it with `verifier.SetT()`. +func NewVerifier(suite Suite, longterm kyber.Scalar, dealerKey kyber.Point, + verifiers []kyber.Point) (*Verifier, error) { + + pub := suite.Point().Mul(longterm, nil) + var ok bool + var index int + for i, v := range verifiers { + if v.Equal(pub) { + ok = true + index = i + break + } + } + if !ok { + return nil, errors.New("vss: public key not found in the list of verifiers") + } + v := &Verifier{ + suite: suite, + longterm: longterm, + dealer: dealerKey, + verifiers: verifiers, + pub: pub, + index: index, + hkdfContext: context(suite, dealerKey, verifiers), + } + return v, nil +} + +// ProcessEncryptedDeal decrypt the deal received from the Dealer. +// If the deal is valid, i.e. the verifier can verify its shares +// against the public coefficients and the signature is valid, an approval +// response is returned and must be broadcasted to every participants +// including the dealer. +// If the deal itself is invalid, it returns a complaint response that must be +// broadcasted to every other participants including the dealer. +// If the deal has already been received, or the signature generation of the +// response failed, it returns an error without any responses. +func (v *Verifier) ProcessEncryptedDeal(e *EncryptedDeal) (*Response, error) { + d, err := v.decryptDeal(e) + if err != nil { + return nil, err + } + if d.SecShare.I != v.index { + return nil, errors.New("vss: verifier got wrong index from deal") + } + + t := int(d.T) + + sid, err := sessionID(v.suite, v.dealer, v.verifiers, d.Commitments, t) + if err != nil { + return nil, err + } + + if v.aggregator == nil { + v.aggregator = newAggregator(v.suite, v.dealer, v.verifiers, d.Commitments, t, d.SessionID) + } + + r := &Response{ + SessionID: sid, + Index: uint32(v.index), + Approved: true, + } + if err = v.VerifyDeal(d, true); err != nil { + r.Approved = false + } + + if err == errDealAlreadyProcessed { + return nil, err + } + + if r.Signature, err = schnorr.Sign(v.suite, v.longterm, r.Hash(v.suite)); err != nil { + return nil, err + } + + if err = v.aggregator.addResponse(r); err != nil { + return nil, err + } + return r, nil +} + +func (v *Verifier) decryptDeal(e *EncryptedDeal) (*Deal, error) { + ephBuff, err := e.DHKey.MarshalBinary() + if err != nil { + return nil, err + } + // verify signature + if err := schnorr.Verify(v.suite, v.dealer, ephBuff, e.Signature); err != nil { + return nil, err + } + + // compute shared key and AES526-GCM cipher + pre := dhExchange(v.suite, v.longterm, e.DHKey) + gcm, err := newAEAD(v.suite.Hash, pre, v.hkdfContext) + if err != nil { + return nil, err + } + decrypted, err := gcm.Open(nil, e.Nonce, e.Cipher, v.hkdfContext) + if err != nil { + return nil, err + } + deal := &Deal{} + err = deal.decode(v.suite, decrypted) + return deal, err +} + +// ProcessResponse analyzes the given response. If it's a valid complaint, the +// verifier should expect to see a Justification from the Dealer. It returns an +// error if it's not a valid response. +// Call `v.DealCertified()` to check if the whole protocol is finished. +func (v *Verifier) ProcessResponse(resp *Response) error { + return v.aggregator.verifyResponse(resp) +} + +// Deal returns the Deal that this verifier has received. It returns +// nil if the deal is not certified or there is not enough approvals. +func (v *Verifier) Deal() *Deal { + if !v.EnoughApprovals() || !v.DealCertified() { + return nil + } + return v.deal +} + +// ProcessJustification takes a DealerResponse and returns an error if +// something went wrong during the verification. If it is the case, that +// probably means the Dealer is acting maliciously. In order to be sure, call +// `v.EnoughApprovals()` and if true, `v.DealCertified()`. +func (v *Verifier) ProcessJustification(dr *Justification) error { + return v.aggregator.verifyJustification(dr) +} + +// Key returns the longterm key pair this verifier is using during this protocol +// run. +func (v *Verifier) Key() (kyber.Scalar, kyber.Point) { + return v.longterm, v.pub +} + +// Index returns the index of the verifier in the list of participants used +// during this run of the protocol. +func (v *Verifier) Index() int { + return v.index +} + +// SessionID returns the session id generated by the Dealer. WARNING: it returns +// an nil slice if the verifier has not received the Deal yet ! +func (v *Verifier) SessionID() []byte { + return v.sid +} + +// RecoverSecret recovers the secret shared by a Dealer by gathering at least t +// Deals from the verifiers. It returns an error if there is not enough Deals or +// if all Deals don't have the same SessionID. +func RecoverSecret(suite Suite, deals []*Deal, n, t int) (kyber.Scalar, error) { + shares := make([]*share.PriShare, len(deals)) + for i, deal := range deals { + // all sids the same + if bytes.Equal(deal.SessionID, deals[0].SessionID) { + shares[i] = deal.SecShare + } else { + return nil, errors.New("vss: all deals need to have same session id") + } + } + return share.RecoverSecret(suite, shares, t, n) +} + +// SetTimeout tells this verifier to consider this moment the maximum time limit. +// it calls cleanVerifiers which will take care of all Verifiers who have not +// responded until now. +func (v *Verifier) SetTimeout() { + v.aggregator.cleanVerifiers() +} + +// aggregator is used to collect all deals, and responses for one protocol run. +// It brings common functionalities for both Dealer and Verifier structs. +type aggregator struct { + suite Suite + dealer kyber.Point + verifiers []kyber.Point + commits []kyber.Point + + responses map[uint32]*Response + sid []byte + deal *Deal + t int + badDealer bool +} + +func newAggregator(suite Suite, dealer kyber.Point, verifiers, commitments []kyber.Point, t int, sid []byte) *aggregator { + agg := &aggregator{ + suite: suite, + dealer: dealer, + verifiers: verifiers, + commits: commitments, + t: t, + sid: sid, + responses: make(map[uint32]*Response), + } + return agg +} + +var errDealAlreadyProcessed = errors.New("vss: verifier already received a deal") + +// VerifyDeal analyzes the deal and returns an error if it's incorrect. If +// inclusion is true, it also returns an error if it the second time this struct +// analyzes a Deal. +func (a *aggregator) VerifyDeal(d *Deal, inclusion bool) error { + if a.deal != nil && inclusion { + return errDealAlreadyProcessed + + } + if a.deal == nil { + a.commits = d.Commitments + a.sid = d.SessionID + a.deal = d + } + + if !validT(int(d.T), a.verifiers) { + return errors.New("vss: invalid t received in Deal") + } + + if !bytes.Equal(a.sid, d.SessionID) { + return errors.New("vss: find different sessionIDs from Deal") + } + + fi := d.SecShare + gi := d.RndShare + if fi.I != gi.I { + return errors.New("vss: not the same index for f and g share in Deal") + } + if fi.I < 0 || fi.I >= len(a.verifiers) { + return errors.New("vss: index out of bounds in Deal") + } + // compute fi * G + gi * H + fig := a.suite.Point().Base().Mul(fi.V, nil) + H := deriveH(a.suite, a.verifiers) + gih := a.suite.Point().Mul(gi.V, H) + ci := a.suite.Point().Add(fig, gih) + + commitPoly := share.NewPubPoly(a.suite, nil, d.Commitments) + + pubShare := commitPoly.Eval(fi.I) + if !ci.Equal(pubShare.V) { + return errors.New("vss: share does not verify against commitments in Deal") + } + return nil +} + +// cleanVerifiers checks the aggregator's response array and creates a StatusComplaint +// response for all verifiers who have no response in the array. +func (a *aggregator) cleanVerifiers() { + for i := range a.verifiers { + if _, ok := a.responses[uint32(i)]; !ok { + a.responses[uint32(i)] = &Response{ + SessionID: a.sid, + Index: uint32(i), + Approved: false, + } + } + } +} + +func (a *aggregator) verifyResponse(r *Response) error { + if !bytes.Equal(r.SessionID, a.sid) { + return errors.New("vss: receiving inconsistent sessionID in response") + } + + pub, ok := findPub(a.verifiers, r.Index) + if !ok { + return errors.New("vss: index out of bounds in response") + } + + if err := schnorr.Verify(a.suite, pub, r.Hash(a.suite), r.Signature); err != nil { + return err + } + + return a.addResponse(r) +} + +func (a *aggregator) verifyJustification(j *Justification) error { + if _, ok := findPub(a.verifiers, j.Index); !ok { + return errors.New("vss: index out of bounds in justification") + } + r, ok := a.responses[j.Index] + if !ok { + return errors.New("vss: no complaints received for this justification") + } + if r.Approved { + return errors.New("vss: justification received for an approval") + } + + if err := a.VerifyDeal(j.Deal, false); err != nil { + // if one response is bad, flag the dealer as malicious + a.badDealer = true + return err + } + r.Approved = true + return nil +} + +func (a *aggregator) addResponse(r *Response) error { + if _, ok := findPub(a.verifiers, r.Index); !ok { + return errors.New("vss: index out of bounds in Complaint") + } + if _, ok := a.responses[r.Index]; ok { + return errors.New("vss: already existing response from same origin") + } + a.responses[r.Index] = r + return nil +} + +// EnoughApprovals returns true if enough verifiers have sent their approval for +// the deal they received. +func (a *aggregator) EnoughApprovals() bool { + var app int + for _, r := range a.responses { + if r.Approved { + app++ + } + } + return app >= a.t +} + +// DealCertified returns true if there has been less than t complaints, all +// Justifications were correct and if EnoughApprovals() returns true. +func (a *aggregator) DealCertified() bool { + // a can be nil if we're calling it before receiving a deal + if a == nil { + return false + } + + var verifiersUnstable int + // Check either a StatusApproval or StatusComplaint for all known verifiers + // i.e. make sure all verifiers are either timed-out or OK. + for i := range a.verifiers { + if _, ok := a.responses[uint32(i)]; !ok { + verifiersUnstable++ + } + } + + tooMuchComplaints := verifiersUnstable > 0 || a.badDealer + return a.EnoughApprovals() && !tooMuchComplaints +} + +// UnsafeSetResponseDKG is an UNSAFE bypass method to allow DKG to use VSS +// that works on basis of approval only. +func (a *aggregator) UnsafeSetResponseDKG(idx uint32, approval bool) { + r := &Response{ + SessionID: a.sid, + Index: uint32(idx), + Approved: approval, + } + + a.addResponse(r) +} + +// MinimumT returns the minimum safe T that is proven to be secure with this +// protocol. It expects n, the total number of participants. +// WARNING: Setting a lower T could make +// the whole protocol insecure. Setting a higher T only makes it harder to +// reconstruct the secret. +func MinimumT(n int) int { + return (n + 1) / 2 +} + +func validT(t int, verifiers []kyber.Point) bool { + return t >= 2 && t <= len(verifiers) && int(uint32(t)) == t +} + +func deriveH(suite Suite, verifiers []kyber.Point) kyber.Point { + var b bytes.Buffer + for _, v := range verifiers { + _, _ = v.MarshalTo(&b) + } + base := suite.Point().Pick(suite.XOF(b.Bytes())) + return base +} + +func findPub(verifiers []kyber.Point, idx uint32) (kyber.Point, bool) { + iidx := int(idx) + if iidx >= len(verifiers) { + return nil, false + } + return verifiers[iidx], true +} + +func sessionID(suite Suite, dealer kyber.Point, verifiers, commitments []kyber.Point, t int) ([]byte, error) { + h := suite.Hash() + _, _ = dealer.MarshalTo(h) + + for _, v := range verifiers { + _, _ = v.MarshalTo(h) + } + + for _, c := range commitments { + _, _ = c.MarshalTo(h) + } + _ = binary.Write(h, binary.LittleEndian, uint32(t)) + + return h.Sum(nil), nil +} + +// Hash returns the Hash representation of the Response +func (r *Response) Hash(s Suite) []byte { + h := s.Hash() + _, _ = h.Write([]byte("response")) + _, _ = h.Write(r.SessionID) + _ = binary.Write(h, binary.LittleEndian, r.Index) + _ = binary.Write(h, binary.LittleEndian, r.Approved) + return h.Sum(nil) +} + +func (d *Deal) decode(s Suite, buff []byte) error { + constructors := make(protobuf.Constructors) + var point kyber.Point + var secret kyber.Scalar + constructors[reflect.TypeOf(&point).Elem()] = func() interface{} { return s.Point() } + constructors[reflect.TypeOf(&secret).Elem()] = func() interface{} { return s.Scalar() } + return protobuf.DecodeWithConstructors(buff, d, constructors) +} + +// Hash returns the hash of a Justification. +func (j *Justification) Hash(s Suite) []byte { + h := s.Hash() + _, _ = h.Write([]byte("justification")) + _, _ = h.Write(j.SessionID) + _ = binary.Write(h, binary.LittleEndian, j.Index) + buff, _ := protobuf.Encode(j.Deal) + _, _ = h.Write(buff) + return h.Sum(nil) +} diff --git a/kyber/share/vss/rabin/vss_test.go b/kyber/share/vss/rabin/vss_test.go new file mode 100644 index 0000000000..87c4c5fc34 --- /dev/null +++ b/kyber/share/vss/rabin/vss_test.go @@ -0,0 +1,609 @@ +package vss + +import ( + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/sign/schnorr" + "go.dedis.ch/protobuf" +) + +var suite = edwards25519.NewBlakeSHA256Ed25519() + +var nbVerifiers = 7 + +var vssThreshold int + +var verifiersPub []kyber.Point +var verifiersSec []kyber.Scalar + +var dealerPub kyber.Point +var dealerSec kyber.Scalar + +var secret kyber.Scalar + +func init() { + verifiersSec, verifiersPub = genCommits(nbVerifiers) + dealerSec, dealerPub = genPair() + secret, _ = genPair() + vssThreshold = MinimumT(nbVerifiers) +} + +func TestVSSWhole(t *testing.T) { + dealer, verifiers := genAll() + + // 1. dispatch deal + resps := make([]*Response, nbVerifiers) + encDeals, err := dealer.EncryptedDeals() + require.Nil(t, err) + for i, d := range encDeals { + resp, err := verifiers[i].ProcessEncryptedDeal(d) + require.Nil(t, err) + resps[i] = resp + } + + // 2. dispatch responses + for _, resp := range resps { + for i, v := range verifiers { + if resp.Index == uint32(i) { + continue + } + require.Nil(t, v.ProcessResponse(resp)) + } + // 2.1. check dealer (no justification here) + j, err := dealer.ProcessResponse(resp) + require.Nil(t, err) + require.Nil(t, j) + } + + // 3. check certified + for _, v := range verifiers { + require.True(t, v.DealCertified()) + } + + // 4. collect deals + deals := make([]*Deal, nbVerifiers) + for i, v := range verifiers { + deals[i] = v.Deal() + } + + // 5. recover + sec, err := RecoverSecret(suite, deals, nbVerifiers, MinimumT(nbVerifiers)) + assert.Nil(t, err) + require.NotNil(t, sec) + assert.Equal(t, dealer.secret.String(), sec.String()) +} + +func TestVSSDealerNew(t *testing.T) { + goodT := MinimumT(nbVerifiers) + _, err := NewDealer(suite, dealerSec, secret, verifiersPub, goodT) + assert.NoError(t, err) + + for _, badT := range []int{0, 1, -4} { + _, err = NewDealer(suite, dealerSec, secret, verifiersPub, badT) + assert.Error(t, err) + } +} + +func TestVSSVerifierNew(t *testing.T) { + randIdx := rand.Int() % len(verifiersPub) + v, err := NewVerifier(suite, verifiersSec[randIdx], dealerPub, verifiersPub) + assert.NoError(t, err) + assert.Equal(t, randIdx, v.index) + + wrongKey := suite.Scalar().Pick(suite.RandomStream()) + _, err = NewVerifier(suite, wrongKey, dealerPub, verifiersPub) + assert.Error(t, err) +} + +func TestVSSShare(t *testing.T) { + dealer, verifiers := genAll() + ver := verifiers[0] + deal, err := dealer.EncryptedDeal(0) + require.Nil(t, err) + + resp, err := ver.ProcessEncryptedDeal(deal) + require.NotNil(t, resp) + require.Equal(t, true, resp.Approved) + require.Nil(t, err) + + aggr := ver.aggregator + + for i := 1; i < aggr.t-1; i++ { + aggr.responses[uint32(i)] = &Response{Approved: true} + } + + ver.SetTimeout() + + // not enough approvals + assert.Nil(t, ver.Deal()) + aggr.responses[uint32(aggr.t)] = &Response{Approved: true} + // deal not certified + aggr.badDealer = true + assert.Nil(t, ver.Deal()) + aggr.badDealer = false + + assert.NotNil(t, ver.Deal()) + +} + +func TestVSSAggregatorEnoughApprovals(t *testing.T) { + dealer := genDealer() + aggr := dealer.aggregator + // just below + for i := 0; i < aggr.t-1; i++ { + aggr.responses[uint32(i)] = &Response{Approved: true} + } + + dealer.SetTimeout() + + assert.False(t, aggr.EnoughApprovals()) + assert.Nil(t, dealer.SecretCommit()) + + aggr.responses[uint32(aggr.t)] = &Response{Approved: true} + assert.True(t, aggr.EnoughApprovals()) + + for i := aggr.t + 1; i < nbVerifiers; i++ { + aggr.responses[uint32(i)] = &Response{Approved: true} + } + assert.True(t, aggr.EnoughApprovals()) + assert.Equal(t, suite.Point().Mul(secret, nil), dealer.SecretCommit()) +} + +func TestVSSAggregatorDealCertified(t *testing.T) { + dealer := genDealer() + aggr := dealer.aggregator + + for i := 0; i < aggr.t; i++ { + aggr.responses[uint32(i)] = &Response{Approved: true} + } + + dealer.SetTimeout() + + assert.True(t, aggr.DealCertified()) + assert.Equal(t, suite.Point().Mul(secret, nil), dealer.SecretCommit()) + // bad dealer response + aggr.badDealer = true + assert.False(t, aggr.DealCertified()) + assert.Nil(t, dealer.SecretCommit()) + // inconsistent state on purpose + // too much complaints + for i := 0; i < aggr.t; i++ { + aggr.responses[uint32(i)] = &Response{Approved: false} + } + assert.False(t, aggr.DealCertified()) +} + +func TestVSSVerifierDecryptDeal(t *testing.T) { + dealer, verifiers := genAll() + v := verifiers[0] + d := dealer.deals[0] + + // all fine + encD, err := dealer.EncryptedDeal(0) + require.Nil(t, err) + decD, err := v.decryptDeal(encD) + require.Nil(t, err) + b1, _ := protobuf.Encode(d) + b2, _ := protobuf.Encode(decD) + assert.Equal(t, b1, b2) + + // wrong dh key + goodDh := encD.DHKey + encD.DHKey = suite.Point() + decD, err = v.decryptDeal(encD) + assert.Error(t, err) + assert.Nil(t, decD) + encD.DHKey = goodDh + + // wrong signature + goodSig := encD.Signature + encD.Signature = randomBytes(32) + decD, err = v.decryptDeal(encD) + assert.Error(t, err) + assert.Nil(t, decD) + encD.Signature = goodSig + + // wrong ciphertext + goodCipher := encD.Cipher + encD.Cipher = randomBytes(len(goodCipher)) + decD, err = v.decryptDeal(encD) + assert.Error(t, err) + assert.Nil(t, decD) + encD.Cipher = goodCipher +} + +func TestVSSVerifierReceiveDeal(t *testing.T) { + dealer, verifiers := genAll() + v := verifiers[0] + d := dealer.deals[0] + + encD, err := dealer.EncryptedDeal(0) + require.Nil(t, err) + + // correct deal + resp, err := v.ProcessEncryptedDeal(encD) + require.NotNil(t, resp) + assert.Equal(t, true, resp.Approved) + assert.Nil(t, err) + assert.Equal(t, v.index, int(resp.Index)) + assert.Equal(t, dealer.sid, resp.SessionID) + assert.Nil(t, schnorr.Verify(suite, v.pub, resp.Hash(suite), resp.Signature)) + assert.Equal(t, v.responses[uint32(v.index)], resp) + + // wrong encryption + goodSig := encD.Signature + encD.Signature = randomBytes(32) + resp, err = v.ProcessEncryptedDeal(encD) + assert.Nil(t, resp) + assert.Error(t, err) + encD.Signature = goodSig + + // wrong index + goodIdx := d.SecShare.I + d.SecShare.I = (goodIdx - 1) % nbVerifiers + encD, _ = dealer.EncryptedDeal(0) + resp, err = v.ProcessEncryptedDeal(encD) + assert.Error(t, err) + assert.Nil(t, resp) + d.SecShare.I = goodIdx + + // wrong commitments + goodCommit := d.Commitments[0] + d.Commitments[0] = suite.Point().Pick(suite.RandomStream()) + encD, _ = dealer.EncryptedDeal(0) + resp, err = v.ProcessEncryptedDeal(encD) + assert.Error(t, err) + assert.Nil(t, resp) + d.Commitments[0] = goodCommit + + // already seen twice + resp, err = v.ProcessEncryptedDeal(encD) + assert.Nil(t, resp) + assert.Error(t, err) + v.aggregator.deal = nil + + // approval already existing from same origin, should never happen right ? + v.aggregator.responses[uint32(v.index)] = &Response{Approved: true} + d.Commitments[0] = suite.Point().Pick(suite.RandomStream()) + resp, err = v.ProcessEncryptedDeal(encD) + assert.Nil(t, resp) + assert.Error(t, err) + d.Commitments[0] = goodCommit + + // valid complaint + v.aggregator.deal = nil + delete(v.aggregator.responses, uint32(v.index)) + d.RndShare.V = suite.Scalar().SetBytes(randomBytes(32)) + resp, err = v.ProcessEncryptedDeal(encD) + assert.NotNil(t, resp) + assert.Equal(t, false, resp.Approved) + assert.Nil(t, err) +} + +func TestVSSAggregatorVerifyJustification(t *testing.T) { + dealer, verifiers := genAll() + v := verifiers[0] + d := dealer.deals[0] + + wrongV := suite.Scalar().Pick(suite.RandomStream()) + goodV := d.SecShare.V + d.SecShare.V = wrongV + encD, _ := dealer.EncryptedDeal(0) + resp, err := v.ProcessEncryptedDeal(encD) + assert.NotNil(t, resp) + assert.Equal(t, false, resp.Approved) + assert.Nil(t, err) + assert.Equal(t, v.responses[uint32(v.index)], resp) + // in tests, pointers point to the same underlying share.. + d.SecShare.V = goodV + + j, err := dealer.ProcessResponse(resp) + + // invalid deal justified + goodV = j.Deal.SecShare.V + j.Deal.SecShare.V = wrongV + err = v.ProcessJustification(j) + assert.Error(t, err) + assert.True(t, v.aggregator.badDealer) + j.Deal.SecShare.V = goodV + v.aggregator.badDealer = false + + // valid complaint + assert.Nil(t, v.ProcessJustification(j)) + + // invalid complaint + resp.SessionID = randomBytes(len(resp.SessionID)) + badJ, err := dealer.ProcessResponse(resp) + assert.Nil(t, badJ) + assert.Error(t, err) + resp.SessionID = dealer.sid + + // no complaints for this justification before + delete(v.aggregator.responses, uint32(v.index)) + assert.Error(t, v.ProcessJustification(j)) + v.aggregator.responses[uint32(v.index)] = resp + +} + +func TestVSSAggregatorVerifyResponseDuplicate(t *testing.T) { + dealer, verifiers := genAll() + v1 := verifiers[0] + v2 := verifiers[1] + //d1 := dealer.deals[0] + //d2 := dealer.deals[1] + encD1, _ := dealer.EncryptedDeal(0) + encD2, _ := dealer.EncryptedDeal(1) + + resp1, err := v1.ProcessEncryptedDeal(encD1) + assert.Nil(t, err) + assert.NotNil(t, resp1) + assert.Equal(t, true, resp1.Approved) + + resp2, err := v2.ProcessEncryptedDeal(encD2) + assert.Nil(t, err) + assert.NotNil(t, resp2) + assert.Equal(t, true, resp2.Approved) + + err = v1.ProcessResponse(resp2) + assert.Nil(t, err) + r, ok := v1.aggregator.responses[uint32(v2.index)] + assert.True(t, ok) + assert.Equal(t, resp2, r) + + err = v1.ProcessResponse(resp2) + assert.Error(t, err) + + delete(v1.aggregator.responses, uint32(v2.index)) + v1.aggregator.responses[uint32(v2.index)] = &Response{Approved: true} + err = v1.ProcessResponse(resp2) + assert.Error(t, err) +} + +func TestVSSAggregatorVerifyResponse(t *testing.T) { + dealer, verifiers := genAll() + v := verifiers[0] + deal := dealer.deals[0] + //goodSec := deal.SecShare.V + wrongSec, _ := genPair() + deal.SecShare.V = wrongSec + encD, _ := dealer.EncryptedDeal(0) + // valid complaint + resp, err := v.ProcessEncryptedDeal(encD) + assert.Nil(t, err) + assert.NotNil(t, resp) + assert.Equal(t, false, resp.Approved) + assert.NotNil(t, v.aggregator) + assert.Equal(t, resp.SessionID, dealer.sid) + + aggr := v.aggregator + r, ok := aggr.responses[uint32(v.index)] + assert.True(t, ok) + assert.Equal(t, false, r.Approved) + + // wrong index + resp.Index = uint32(len(verifiersPub)) + sig, err := schnorr.Sign(suite, v.longterm, resp.Hash(suite)) + resp.Signature = sig + assert.Error(t, aggr.verifyResponse(resp)) + resp.Index = 0 + + // wrong signature + goodSig := resp.Signature + resp.Signature = randomBytes(len(goodSig)) + assert.Error(t, aggr.verifyResponse(resp)) + resp.Signature = goodSig + + // wrongID + wrongID := randomBytes(len(resp.SessionID)) + goodID := resp.SessionID + resp.SessionID = wrongID + assert.Error(t, aggr.verifyResponse(resp)) + resp.SessionID = goodID +} + +func TestVSSAggregatorVerifyDeal(t *testing.T) { + dealer := genDealer() + aggr := dealer.aggregator + deals := dealer.deals + + // OK + deal := deals[0] + err := aggr.VerifyDeal(deal, true) + assert.NoError(t, err) + assert.NotNil(t, aggr.deal) + + // already received deal + err = aggr.VerifyDeal(deal, true) + assert.Error(t, err) + + // wrong T + wrongT := uint32(1) + goodT := deal.T + deal.T = wrongT + assert.Error(t, aggr.VerifyDeal(deal, false)) + deal.T = goodT + + // wrong SessionID + goodSid := deal.SessionID + deal.SessionID = make([]byte, 32) + assert.Error(t, aggr.VerifyDeal(deal, false)) + deal.SessionID = goodSid + + // index different in one share + goodI := deal.RndShare.I + deal.RndShare.I = goodI + 1 + assert.Error(t, aggr.VerifyDeal(deal, false)) + deal.RndShare.I = goodI + + // index not in bounds + deal.SecShare.I = -1 + assert.Error(t, aggr.VerifyDeal(deal, false)) + deal.SecShare.I = len(verifiersPub) + assert.Error(t, aggr.VerifyDeal(deal, false)) + + // shares invalid in respect to the commitments + wrongSec, _ := genPair() + deal.SecShare.V = wrongSec + assert.Error(t, aggr.VerifyDeal(deal, false)) +} + +func TestVSSAggregatorAddComplaint(t *testing.T) { + dealer := genDealer() + aggr := dealer.aggregator + + var idx uint32 = 1 + c := &Response{ + Index: idx, + Approved: false, + } + // ok + assert.Nil(t, aggr.addResponse(c)) + assert.Equal(t, aggr.responses[idx], c) + + // response already there + assert.Error(t, aggr.addResponse(c)) + delete(aggr.responses, idx) + +} + +func TestVSSAggregatorCleanVerifiers(t *testing.T) { + dealer := genDealer() + aggr := dealer.aggregator + + for i := 0; i < aggr.t; i++ { + aggr.responses[uint32(i)] = &Response{Approved: true} + } + + assert.True(t, aggr.EnoughApprovals()) + assert.False(t, aggr.DealCertified()) + + aggr.cleanVerifiers() + + assert.True(t, aggr.DealCertified()) +} + +func TestVSSDealerSetTimeout(t *testing.T) { + dealer := genDealer() + aggr := dealer.aggregator + + for i := 0; i < aggr.t; i++ { + aggr.responses[uint32(i)] = &Response{Approved: true} + } + + assert.True(t, aggr.EnoughApprovals()) + assert.False(t, aggr.DealCertified()) + + dealer.SetTimeout() + + assert.True(t, aggr.DealCertified()) +} + +func TestVSSVerifierSetTimeout(t *testing.T) { + dealer, verifiers := genAll() + ver := verifiers[0] + + encD, err := dealer.EncryptedDeal(0) + + require.Nil(t, err) + + resp, err := ver.ProcessEncryptedDeal(encD) + + require.Nil(t, err) + require.NotNil(t, resp) + + aggr := ver.aggregator + + for i := 0; i < aggr.t; i++ { + aggr.responses[uint32(i)] = &Response{Approved: true} + } + + assert.True(t, aggr.EnoughApprovals()) + assert.False(t, aggr.DealCertified()) + + ver.SetTimeout() + + assert.True(t, aggr.DealCertified()) +} + +func TestVSSSessionID(t *testing.T) { + dealer, _ := NewDealer(suite, dealerSec, secret, verifiersPub, vssThreshold) + commitments := dealer.deals[0].Commitments + sid, err := sessionID(suite, dealerPub, verifiersPub, commitments, dealer.t) + assert.NoError(t, err) + + sid2, err2 := sessionID(suite, dealerPub, verifiersPub, commitments, dealer.t) + assert.NoError(t, err2) + assert.Equal(t, sid, sid2) + + wrongDealerPub := suite.Point().Add(dealerPub, dealerPub) + + sid3, err3 := sessionID(suite, wrongDealerPub, verifiersPub, commitments, dealer.t) + assert.NoError(t, err3) + assert.NotEqual(t, sid3, sid2) +} + +func TestVSSFindPub(t *testing.T) { + p, ok := findPub(verifiersPub, 0) + assert.True(t, ok) + assert.Equal(t, verifiersPub[0], p) + + p, ok = findPub(verifiersPub, uint32(len(verifiersPub))) + assert.False(t, ok) + assert.Nil(t, p) +} + +func TestVSSDHExchange(t *testing.T) { + pub := suite.Point().Base() + priv := suite.Scalar().Pick(suite.RandomStream()) + point := dhExchange(suite, priv, pub) + assert.Equal(t, pub.Mul(priv, nil).String(), point.String()) +} + +func TestVSSContext(t *testing.T) { + c := context(suite, dealerPub, verifiersPub) + assert.Len(t, c, keySize) +} + +func genPair() (kyber.Scalar, kyber.Point) { + secret := suite.Scalar().Pick(suite.RandomStream()) + public := suite.Point().Mul(secret, nil) + return secret, public +} + +func genCommits(n int) ([]kyber.Scalar, []kyber.Point) { + var secrets = make([]kyber.Scalar, n) + var publics = make([]kyber.Point, n) + for i := 0; i < n; i++ { + secrets[i], publics[i] = genPair() + } + return secrets, publics +} + +func genDealer() *Dealer { + d, _ := NewDealer(suite, dealerSec, secret, verifiersPub, vssThreshold) + return d +} + +func genAll() (*Dealer, []*Verifier) { + dealer := genDealer() + var verifiers = make([]*Verifier, nbVerifiers) + for i := 0; i < nbVerifiers; i++ { + v, _ := NewVerifier(suite, verifiersSec[i], dealerPub, verifiersPub) + verifiers[i] = v + } + return dealer, verifiers +} + +func randomBytes(n int) []byte { + var buff = make([]byte, n) + _, err := rand.Read(buff) + if err != nil { + panic(err) + } + return buff +} diff --git a/kyber/shuffle/biffle.go b/kyber/shuffle/biffle.go new file mode 100644 index 0000000000..af0ec72d3a --- /dev/null +++ b/kyber/shuffle/biffle.go @@ -0,0 +1,91 @@ +package shuffle + +import ( + "crypto/cipher" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/proof" + "go.dedis.ch/kyber/v3/util/random" +) + +func bifflePred() proof.Predicate { + + // Branch 0 of either/or proof (for bit=0) + rep000 := proof.Rep("Xbar0-X0", "beta0", "G") + rep001 := proof.Rep("Ybar0-Y0", "beta0", "H") + rep010 := proof.Rep("Xbar1-X1", "beta1", "G") + rep011 := proof.Rep("Ybar1-Y1", "beta1", "H") + + // Branch 1 of either/or proof (for bit=1) + rep100 := proof.Rep("Xbar0-X1", "beta1", "G") + rep101 := proof.Rep("Ybar0-Y1", "beta1", "H") + rep110 := proof.Rep("Xbar1-X0", "beta0", "G") + rep111 := proof.Rep("Ybar1-Y0", "beta0", "H") + + and0 := proof.And(rep000, rep001, rep010, rep011) + and1 := proof.And(rep100, rep101, rep110, rep111) + + or := proof.Or(and0, and1) + return or +} + +func bifflePoints(suite Suite, G, H kyber.Point, + X, Y, Xbar, Ybar [2]kyber.Point) map[string]kyber.Point { + + return map[string]kyber.Point{ + "G": G, + "H": H, + "Xbar0-X0": suite.Point().Sub(Xbar[0], X[0]), + "Ybar0-Y0": suite.Point().Sub(Ybar[0], Y[0]), + "Xbar1-X1": suite.Point().Sub(Xbar[1], X[1]), + "Ybar1-Y1": suite.Point().Sub(Ybar[1], Y[1]), + "Xbar0-X1": suite.Point().Sub(Xbar[0], X[1]), + "Ybar0-Y1": suite.Point().Sub(Ybar[0], Y[1]), + "Xbar1-X0": suite.Point().Sub(Xbar[1], X[0]), + "Ybar1-Y0": suite.Point().Sub(Ybar[1], Y[0])} +} + +// Biffle is a binary shuffle ("biffle") for 2 ciphertexts based on general ZKPs. +func Biffle(suite Suite, G, H kyber.Point, + X, Y [2]kyber.Point, rand cipher.Stream) ( + Xbar, Ybar [2]kyber.Point, prover proof.Prover) { + + // Pick the single-bit permutation. + var buf [1]byte + random.Bytes(buf[:], rand) + bit := int(buf[0] & 1) + + // Pick a fresh ElGamal blinding factor for each pair + var beta [2]kyber.Scalar + for i := 0; i < 2; i++ { + beta[i] = suite.Scalar().Pick(rand) + } + + // Create the output pair vectors + for i := 0; i < 2; i++ { + piI := i ^ bit + Xbar[i] = suite.Point().Mul(beta[piI], G) + Xbar[i].Add(Xbar[i], X[piI]) + Ybar[i] = suite.Point().Mul(beta[piI], H) + Ybar[i].Add(Ybar[i], Y[piI]) + } + + or := bifflePred() + secrets := map[string]kyber.Scalar{ + "beta0": beta[0], + "beta1": beta[1]} + points := bifflePoints(suite, G, H, X, Y, Xbar, Ybar) + choice := map[proof.Predicate]int{or: bit} + prover = or.Prover(suite, secrets, points, choice) + return +} + +// BiffleVerifier returns a verifier of the biffle +func BiffleVerifier(suite Suite, G, H kyber.Point, + X, Y, Xbar, Ybar [2]kyber.Point) ( + verifier proof.Verifier) { + + or := bifflePred() + points := bifflePoints(suite, G, H, X, Y, Xbar, Ybar) + return or.Verifier(suite, points) +} diff --git a/kyber/shuffle/biffle_test.go b/kyber/shuffle/biffle_test.go new file mode 100644 index 0000000000..2b73cde33b --- /dev/null +++ b/kyber/shuffle/biffle_test.go @@ -0,0 +1,63 @@ +package shuffle + +import ( + "testing" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/proof" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +func TestBiffle(t *testing.T) { + rand := blake2xb.New(nil) + s := edwards25519.NewBlakeSHA256Ed25519WithRand(rand) + biffleTest(s, N) +} + +func biffleTest(suite Suite, N int) { + rand := suite.RandomStream() + + // Create a "server" private/public keypair + h := suite.Scalar().Pick(rand) + H := suite.Point().Mul(h, nil) + + // Create a set of ephemeral "client" keypairs to shuffle + var c [2]kyber.Scalar + var C [2]kyber.Point + // fmt.Println("\nclient keys:") + for i := 0; i < 2; i++ { + c[i] = suite.Scalar().Pick(rand) + C[i] = suite.Point().Mul(c[i], nil) + // fmt.Println(" "+C[i].String()) + } + + // ElGamal-encrypt all these keypairs with the "server" key + var X, Y [2]kyber.Point + r := suite.Scalar() // temporary + for i := 0; i < 2; i++ { + r.Pick(rand) + X[i] = suite.Point().Mul(r, nil) + Y[i] = suite.Point().Mul(r, H) // ElGamal blinding factor + Y[i].Add(Y[i], C[i]) // Encrypted client public key + } + + // Repeat only the actual shuffle portion for test purposes. + for i := 0; i < N; i++ { + + // Do a key-shuffle + Xbar, Ybar, prover := Biffle(suite, nil, H, X, Y, rand) + prf, err := proof.HashProve(suite, "Biffle", prover) + if err != nil { + panic("Biffle proof failed: " + err.Error()) + } + //fmt.Printf("proof:\n%s\n",hex.Dump(prf)) + + // Check it + verifier := BiffleVerifier(suite, nil, H, X, Y, Xbar, Ybar) + err = proof.HashVerify(suite, "Biffle", verifier, prf) + if err != nil { + panic("Biffle verify failed: " + err.Error()) + } + } +} diff --git a/kyber/shuffle/pair.go b/kyber/shuffle/pair.go new file mode 100644 index 0000000000..9be69550f0 --- /dev/null +++ b/kyber/shuffle/pair.go @@ -0,0 +1,379 @@ +// Package shuffle implements Andrew Neff's verifiable shuffle proof scheme. +// Neff's shuffle proof algorithm as implemented here is described in the paper +// "Verifiable Mixing (Shuffling) of ElGamal Pairs", April 2004. +// +// The PairShuffle type implements the general algorithm +// to prove the correctness of a shuffle of arbitrary ElGamal pairs. +// This will be the primary API of interest for most applications. +// For basic usage, the caller should first instantiate a PairShuffle object, +// then invoke PairShuffle.Init() to initialize the shuffle parameters, +// and finally invoke PairShuffle.Shuffle() to shuffle +// a list of ElGamal pairs, yielding a list of re-randomized pairs +// and a noninteractive proof of its correctness. +// +// The SimpleShuffle type implements Neff's more restrictive "simple shuffle", +// which requires the prover to know the discrete logarithms +// of all the individual ElGamal ciphertexts involved in the shuffle. +// The general PairShuffle builds on this SimpleShuffle scheme, +// but SimpleShuffle may also be used by itself in situations +// that satisfy its assumptions, and is more efficient. +package shuffle + +import ( + "crypto/cipher" + "encoding/binary" + "errors" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/proof" + "go.dedis.ch/kyber/v3/util/random" +) + +// Suite wraps the functionalities needed by the shuffle/ package. These are the +// same functionatlities needed by the proof/ package. +type Suite proof.Suite + +// XX these could all be inlined into PairShuffleProof; do we want to? + +// XX the Zs in front of some field names are a kludge to make them +// accessible via the reflection API, +// which refuses to touch unexported fields in a struct. + +// P (Prover) step 1: public commitments +type ega1 struct { + Gamma kyber.Point + A, C, U, W []kyber.Point + Lambda1, Lambda2 kyber.Point +} + +// V (Verifier) step 2: random challenge t +type ega2 struct { + Zrho []kyber.Scalar +} + +// P step 3: Theta vectors +type ega3 struct { + D []kyber.Point +} + +// V step 4: random challenge c +type ega4 struct { + Zlambda kyber.Scalar +} + +// P step 5: alpha vector +type ega5 struct { + Zsigma []kyber.Scalar + Ztau kyber.Scalar +} + +// P and V, step 5: simple k-shuffle proof +type ega6 struct { + SimpleShuffle +} + +// PairShuffle creates a proof of the correctness of a shuffle +// of a series of ElGamal pairs. +// +// The caller must first invoke Init() +// to establish the cryptographic parameters for the shuffle: +// in particular, the relevant cryptographic Group, +// and the number of ElGamal pairs to be shuffled. +// +// The caller then may either perform its own shuffle, +// according to a permutation of the caller's choosing, +// and invoke Prove() to create a proof of its correctness; +// or alternatively the caller may simply invoke Shuffle() +// to pick a random permutation, compute the shuffle, +// and compute the correctness proof. +type PairShuffle struct { + grp kyber.Group + k int + p1 ega1 + v2 ega2 + p3 ega3 + v4 ega4 + p5 ega5 + pv6 SimpleShuffle +} + +// Init creates a new PairShuffleProof instance for a k-element ElGamal pair shuffle. +// This protocol follows the ElGamal Pair Shuffle defined in section 4 of +// Andrew Neff, "Verifiable Mixing (Shuffling) of ElGamal Pairs", 2004. +func (ps *PairShuffle) Init(grp kyber.Group, k int) *PairShuffle { + + if k <= 1 { + panic("can't shuffle permutation of size <= 1") + } + + // Create a well-formed PairShuffleProof with arrays correctly sized. + ps.grp = grp + ps.k = k + ps.p1.A = make([]kyber.Point, k) + ps.p1.C = make([]kyber.Point, k) + ps.p1.U = make([]kyber.Point, k) + ps.p1.W = make([]kyber.Point, k) + ps.v2.Zrho = make([]kyber.Scalar, k) + ps.p3.D = make([]kyber.Point, k) + ps.p5.Zsigma = make([]kyber.Scalar, k) + ps.pv6.Init(grp, k) + + return ps +} + +// Prove returns an error if the shuffle is not correct. +func (ps *PairShuffle) Prove( + pi []int, g, h kyber.Point, beta []kyber.Scalar, + X, Y []kyber.Point, rand cipher.Stream, + ctx proof.ProverContext) error { + + grp := ps.grp + k := ps.k + if k != len(pi) || k != len(beta) { + panic("mismatched vector lengths") + } + + // Compute pi^-1 inverse permutation + piinv := make([]int, k) + for i := 0; i < k; i++ { + piinv[pi[i]] = i + } + + // P step 1 + p1 := &ps.p1 + z := grp.Scalar() // scratch + + // pick random secrets + u := make([]kyber.Scalar, k) + w := make([]kyber.Scalar, k) + a := make([]kyber.Scalar, k) + var tau0, nu, gamma kyber.Scalar + ctx.PriRand(u, w, a, &tau0, &nu, &gamma) + + // compute public commits + p1.Gamma = grp.Point().Mul(gamma, g) + wbeta := grp.Scalar() // scratch + wbetasum := grp.Scalar().Set(tau0) + p1.Lambda1 = grp.Point().Null() + p1.Lambda2 = grp.Point().Null() + XY := grp.Point() // scratch + wu := grp.Scalar() // scratch + for i := 0; i < k; i++ { + p1.A[i] = grp.Point().Mul(a[i], g) + p1.C[i] = grp.Point().Mul(z.Mul(gamma, a[pi[i]]), g) + p1.U[i] = grp.Point().Mul(u[i], g) + p1.W[i] = grp.Point().Mul(z.Mul(gamma, w[i]), g) + wbetasum.Add(wbetasum, wbeta.Mul(w[i], beta[pi[i]])) + p1.Lambda1.Add(p1.Lambda1, XY.Mul(wu.Sub(w[piinv[i]], u[i]), X[i])) + p1.Lambda2.Add(p1.Lambda2, XY.Mul(wu.Sub(w[piinv[i]], u[i]), Y[i])) + } + p1.Lambda1.Add(p1.Lambda1, XY.Mul(wbetasum, g)) + p1.Lambda2.Add(p1.Lambda2, XY.Mul(wbetasum, h)) + if err := ctx.Put(p1); err != nil { + return err + } + + // V step 2 + v2 := &ps.v2 + if err := ctx.PubRand(v2); err != nil { + return err + } + B := make([]kyber.Point, k) + for i := 0; i < k; i++ { + P := grp.Point().Mul(v2.Zrho[i], g) + B[i] = P.Sub(P, p1.U[i]) + } + + // P step 3 + p3 := &ps.p3 + b := make([]kyber.Scalar, k) + for i := 0; i < k; i++ { + b[i] = grp.Scalar().Sub(v2.Zrho[i], u[i]) + } + d := make([]kyber.Scalar, k) + for i := 0; i < k; i++ { + d[i] = grp.Scalar().Mul(gamma, b[pi[i]]) + p3.D[i] = grp.Point().Mul(d[i], g) + } + if err := ctx.Put(p3); err != nil { + return err + } + + // V step 4 + v4 := &ps.v4 + if err := ctx.PubRand(v4); err != nil { + return err + } + + // P step 5 + p5 := &ps.p5 + r := make([]kyber.Scalar, k) + for i := 0; i < k; i++ { + r[i] = grp.Scalar().Add(a[i], z.Mul(v4.Zlambda, b[i])) + } + s := make([]kyber.Scalar, k) + for i := 0; i < k; i++ { + s[i] = grp.Scalar().Mul(gamma, r[pi[i]]) + } + p5.Ztau = grp.Scalar().Neg(tau0) + for i := 0; i < k; i++ { + p5.Zsigma[i] = grp.Scalar().Add(w[i], b[pi[i]]) + p5.Ztau.Add(p5.Ztau, z.Mul(b[i], beta[i])) + } + if err := ctx.Put(p5); err != nil { + return err + } + + // P,V step 6: embedded simple k-shuffle proof + return ps.pv6.Prove(g, gamma, r, s, rand, ctx) +} + +// Verify ElGamal Pair Shuffle proofs. +func (ps *PairShuffle) Verify( + g, h kyber.Point, X, Y, Xbar, Ybar []kyber.Point, + ctx proof.VerifierContext) error { + + // Validate all vector lengths + grp := ps.grp + k := ps.k + if len(X) != k || len(Y) != k || len(Xbar) != k || len(Ybar) != k { + panic("mismatched vector lengths") + } + + // P step 1 + p1 := &ps.p1 + if err := ctx.Get(p1); err != nil { + return err + } + + // V step 2 + v2 := &ps.v2 + if err := ctx.PubRand(v2); err != nil { + return err + } + B := make([]kyber.Point, k) + for i := 0; i < k; i++ { + P := grp.Point().Mul(v2.Zrho[i], g) + B[i] = P.Sub(P, p1.U[i]) + } + + // P step 3 + p3 := &ps.p3 + if err := ctx.Get(p3); err != nil { + return err + } + + // V step 4 + v4 := &ps.v4 + if err := ctx.PubRand(v4); err != nil { + return err + } + + // P step 5 + p5 := &ps.p5 + if err := ctx.Get(p5); err != nil { + return err + } + + // P,V step 6: simple k-shuffle + if err := ps.pv6.Verify(g, p1.Gamma, ctx); err != nil { + return err + } + + // V step 7 + Phi1 := grp.Point().Null() + Phi2 := grp.Point().Null() + P := grp.Point() // scratch + Q := grp.Point() // scratch + for i := 0; i < k; i++ { + Phi1 = Phi1.Add(Phi1, P.Mul(p5.Zsigma[i], Xbar[i])) // (31) + Phi1 = Phi1.Sub(Phi1, P.Mul(v2.Zrho[i], X[i])) + Phi2 = Phi2.Add(Phi2, P.Mul(p5.Zsigma[i], Ybar[i])) // (32) + Phi2 = Phi2.Sub(Phi2, P.Mul(v2.Zrho[i], Y[i])) + // println("i",i) + if !P.Mul(p5.Zsigma[i], p1.Gamma).Equal( // (33) + Q.Add(p1.W[i], p3.D[i])) { + return errors.New("invalid PairShuffleProof") + } + } + // println("last") + // println("Phi1",Phi1.String()); + // println("Phi2",Phi2.String()); + // println("1",P.Add(p1.Lambda1,Q.Mul(g,p5.Ztau)).String()); + // println("2",P.Add(p1.Lambda2,Q.Mul(h,p5.Ztau)).String()); + if !P.Add(p1.Lambda1, Q.Mul(p5.Ztau, g)).Equal(Phi1) || // (34) + !P.Add(p1.Lambda2, Q.Mul(p5.Ztau, h)).Equal(Phi2) { // (35) + return errors.New("invalid PairShuffleProof") + } + + return nil +} + +// Shuffle randomly shuffles and re-randomizes a set of ElGamal pairs, +// producing a correctness proof in the process. +// Returns (Xbar,Ybar), the shuffled and randomized pairs. +// If g or h is nil, the standard base point is used. +func Shuffle(group kyber.Group, g, h kyber.Point, X, Y []kyber.Point, + rand cipher.Stream) (XX, YY []kyber.Point, P proof.Prover) { + + k := len(X) + if k != len(Y) { + panic("X,Y vectors have inconsistent length") + } + + ps := PairShuffle{} + ps.Init(group, k) + + // Pick a random permutation + pi := make([]int, k) + for i := 0; i < k; i++ { // Initialize a trivial permutation + pi[i] = i + } + for i := k - 1; i > 0; i-- { // Shuffle by random swaps + j := int(randUint64(rand) % uint64(i+1)) + if j != i { + t := pi[j] + pi[j] = pi[i] + pi[i] = t + } + } + + // Pick a fresh ElGamal blinding factor for each pair + beta := make([]kyber.Scalar, k) + for i := 0; i < k; i++ { + beta[i] = ps.grp.Scalar().Pick(rand) + } + + // Create the output pair vectors + Xbar := make([]kyber.Point, k) + Ybar := make([]kyber.Point, k) + for i := 0; i < k; i++ { + Xbar[i] = ps.grp.Point().Mul(beta[pi[i]], g) + Xbar[i].Add(Xbar[i], X[pi[i]]) + Ybar[i] = ps.grp.Point().Mul(beta[pi[i]], h) + Ybar[i].Add(Ybar[i], Y[pi[i]]) + } + + prover := func(ctx proof.ProverContext) error { + return ps.Prove(pi, g, h, beta, X, Y, rand, ctx) + } + return Xbar, Ybar, prover +} + +// randUint64 chooses a uniform random uint64 +func randUint64(rand cipher.Stream) uint64 { + b := random.Bits(64, false, rand) + return binary.BigEndian.Uint64(b) +} + +// Verifier produces a Sigma-protocol verifier to check the correctness of a shuffle. +func Verifier(group kyber.Group, g, h kyber.Point, + X, Y, Xbar, Ybar []kyber.Point) proof.Verifier { + + ps := PairShuffle{} + ps.Init(group, len(X)) + verifier := func(ctx proof.VerifierContext) error { + return ps.Verify(g, h, X, Y, Xbar, Ybar, ctx) + } + return verifier +} diff --git a/kyber/shuffle/shuffle_test.go b/kyber/shuffle/shuffle_test.go new file mode 100644 index 0000000000..c46fb1323f --- /dev/null +++ b/kyber/shuffle/shuffle_test.go @@ -0,0 +1,66 @@ +package shuffle + +import ( + "testing" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/proof" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +var k = 5 +var N = 10 + +func TestShuffle(t *testing.T) { + s := edwards25519.NewBlakeSHA256Ed25519WithRand(blake2xb.New(nil)) + shuffleTest(s, k, N) +} + +func shuffleTest(suite Suite, k, N int) { + rand := suite.RandomStream() + + // Create a "server" private/public keypair + h := suite.Scalar().Pick(rand) + H := suite.Point().Mul(h, nil) + + // Create a set of ephemeral "client" keypairs to shuffle + c := make([]kyber.Scalar, k) + C := make([]kyber.Point, k) + // fmt.Println("\nclient keys:") + for i := 0; i < k; i++ { + c[i] = suite.Scalar().Pick(rand) + C[i] = suite.Point().Mul(c[i], nil) + // fmt.Println(" "+C[i].String()) + } + + // ElGamal-encrypt all these keypairs with the "server" key + X := make([]kyber.Point, k) + Y := make([]kyber.Point, k) + r := suite.Scalar() // temporary + for i := 0; i < k; i++ { + r.Pick(rand) + X[i] = suite.Point().Mul(r, nil) + Y[i] = suite.Point().Mul(r, H) // ElGamal blinding factor + Y[i].Add(Y[i], C[i]) // Encrypted client public key + } + + // Repeat only the actual shuffle portion for test purposes. + for i := 0; i < N; i++ { + + // Do a key-shuffle + Xbar, Ybar, prover := Shuffle(suite, nil, H, X, Y, rand) + prf, err := proof.HashProve(suite, "PairShuffle", prover) + if err != nil { + panic("Shuffle proof failed: " + err.Error()) + } + //fmt.Printf("proof:\n%s\n",hex.Dump(prf)) + + // Check it + verifier := Verifier(suite, nil, H, X, Y, Xbar, Ybar) + err = proof.HashVerify(suite, "PairShuffle", verifier, prf) + if err != nil { + panic("Shuffle verify failed: " + err.Error()) + } + } +} diff --git a/kyber/shuffle/simple.go b/kyber/shuffle/simple.go new file mode 100644 index 0000000000..7f7149815c --- /dev/null +++ b/kyber/shuffle/simple.go @@ -0,0 +1,256 @@ +package shuffle + +import ( + "crypto/cipher" + "errors" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/proof" +) + +// XX the Zs in front of some field names are a kludge to make them +// accessible via the reflection API, +// which refuses to touch unexported fields in a struct. + +// P (Prover) step 0: public inputs to the simple k-shuffle. +type ssa0 struct { + X []kyber.Point + Y []kyber.Point +} + +// V (Verifier) step 1: random challenge t +type ssa1 struct { + Zt kyber.Scalar +} + +// P step 2: Theta vectors +type ssa2 struct { + Theta []kyber.Point +} + +// V step 3: random challenge c +type ssa3 struct { + Zc kyber.Scalar +} + +// P step 4: alpha vector +type ssa4 struct { + Zalpha []kyber.Scalar +} + +// SimpleShuffle is the "Simple k-shuffle" defined in section 3 of +// Neff, "Verifiable Mixing (Shuffling) of ElGamal Pairs", 2004. +type SimpleShuffle struct { + grp kyber.Group + p0 ssa0 + v1 ssa1 + p2 ssa2 + v3 ssa3 + p4 ssa4 +} + +// Simple helper to compute G^{ab-cd} for Theta vector computation. +func thenc(grp kyber.Group, G kyber.Point, + a, b, c, d kyber.Scalar) kyber.Point { + + var ab, cd kyber.Scalar + if a != nil { + ab = grp.Scalar().Mul(a, b) + } else { + ab = grp.Scalar().Zero() + } + if c != nil { + if d != nil { + cd = grp.Scalar().Mul(c, d) + } else { + cd = c + } + } else { + cd = grp.Scalar().Zero() + } + return grp.Point().Mul(ab.Sub(ab, cd), G) +} + +// Init initializes the simple shuffle with the given group and the k parameter +// from the paper. +func (ss *SimpleShuffle) Init(grp kyber.Group, k int) *SimpleShuffle { + ss.grp = grp + ss.p0.X = make([]kyber.Point, k) + ss.p0.Y = make([]kyber.Point, k) + ss.p2.Theta = make([]kyber.Point, 2*k) + ss.p4.Zalpha = make([]kyber.Scalar, 2*k-1) + return ss +} + +// Prove the "Simple k-shuffle" defined in section 3 of +// Neff, "Verifiable Mixing (Shuffling) of ElGamal Pairs", 2004. +// The Scalar vector y must be a permutation of Scalar vector x +// but with all elements multiplied by common Scalar gamma. +func (ss *SimpleShuffle) Prove(G kyber.Point, gamma kyber.Scalar, + x, y []kyber.Scalar, rand cipher.Stream, + ctx proof.ProverContext) error { + + grp := ss.grp + + k := len(x) + if k <= 1 { + panic("can't shuffle length 1 vector") + } + if k != len(y) { + panic("mismatched vector lengths") + } + + // // Dump input vectors to show their correspondences + // for i := 0; i < k; i++ { + // println("x",grp.Scalar().Mul(gamma,x[i]).String()) + // } + // for i := 0; i < k; i++ { + // println("y",y[i].String()) + // } + + // Step 0: inputs + for i := 0; i < k; i++ { // (4) + ss.p0.X[i] = grp.Point().Mul(x[i], G) + ss.p0.Y[i] = grp.Point().Mul(y[i], G) + } + if err := ctx.Put(ss.p0); err != nil { + return err + } + + // V step 1 + if err := ctx.PubRand(&ss.v1); err != nil { + return err + } + t := ss.v1.Zt + + // P step 2 + gammaT := grp.Scalar().Mul(gamma, t) + xhat := make([]kyber.Scalar, k) + yhat := make([]kyber.Scalar, k) + for i := 0; i < k; i++ { // (5) and (6) xhat,yhat vectors + xhat[i] = grp.Scalar().Sub(x[i], t) + yhat[i] = grp.Scalar().Sub(y[i], gammaT) + } + thlen := 2*k - 1 // (7) theta and Theta vectors + theta := make([]kyber.Scalar, thlen) + ctx.PriRand(theta) + Theta := make([]kyber.Point, thlen+1) + Theta[0] = thenc(grp, G, nil, nil, theta[0], yhat[0]) + for i := 1; i < k; i++ { + Theta[i] = thenc(grp, G, theta[i-1], xhat[i], + theta[i], yhat[i]) + } + for i := k; i < thlen; i++ { + Theta[i] = thenc(grp, G, theta[i-1], gamma, + theta[i], nil) + } + Theta[thlen] = thenc(grp, G, theta[thlen-1], gamma, nil, nil) + ss.p2.Theta = Theta + if err := ctx.Put(ss.p2); err != nil { + return err + } + + // V step 3 + if err := ctx.PubRand(&ss.v3); err != nil { + return err + } + c := ss.v3.Zc + + // P step 4 + alpha := make([]kyber.Scalar, thlen) + runprod := grp.Scalar().Set(c) + for i := 0; i < k; i++ { // (8) + runprod.Mul(runprod, xhat[i]) + runprod.Div(runprod, yhat[i]) + alpha[i] = grp.Scalar().Add(theta[i], runprod) + } + gammainv := grp.Scalar().Inv(gamma) + rungamma := grp.Scalar().Set(c) + for i := 1; i < k; i++ { + rungamma.Mul(rungamma, gammainv) + alpha[thlen-i] = grp.Scalar().Add(theta[thlen-i], rungamma) + } + ss.p4.Zalpha = alpha + return ctx.Put(ss.p4) +} + +// Simple helper to verify Theta elements, +// by checking whether A^a*B^-b = T. +// P,Q,s are simply "scratch" kyber.Point/Scalars reused for efficiency. +func thver(A, B, T, P, Q kyber.Point, a, b, s kyber.Scalar) bool { + P.Mul(a, A) + Q.Mul(s.Neg(b), B) + P.Add(P, Q) + return P.Equal(T) +} + +// Verify for Neff simple k-shuffle proofs. +func (ss *SimpleShuffle) Verify(G, Gamma kyber.Point, + ctx proof.VerifierContext) error { + + grp := ss.grp + + // extract proof transcript + X := ss.p0.X + Y := ss.p0.Y + Theta := ss.p2.Theta + alpha := ss.p4.Zalpha + + // Validate all vector lengths + k := len(Y) + thlen := 2*k - 1 + if k <= 1 || len(Y) != k || len(Theta) != thlen+1 || + len(alpha) != thlen { + return errors.New("malformed SimpleShuffleProof") + } + + // check verifiable challenges (usually by reproducing a hash) + if err := ctx.Get(ss.p0); err != nil { + return err + } + if err := ctx.PubRand(&ss.v1); err != nil { // fills in v1 + return err + } + t := ss.v1.Zt + if err := ctx.Get(ss.p2); err != nil { + return err + } + if err := ctx.PubRand(&ss.v3); err != nil { // fills in v3 + return err + } + c := ss.v3.Zc + if err := ctx.Get(ss.p4); err != nil { + return err + } + + // Verifier step 5 + negt := grp.Scalar().Neg(t) + U := grp.Point().Mul(negt, G) + W := grp.Point().Mul(negt, Gamma) + Xhat := make([]kyber.Point, k) + Yhat := make([]kyber.Point, k) + for i := 0; i < k; i++ { + Xhat[i] = grp.Point().Add(X[i], U) + Yhat[i] = grp.Point().Add(Y[i], W) + } + P := grp.Point() // scratch variables + Q := grp.Point() + s := grp.Scalar() + good := true + good = good && thver(Xhat[0], Yhat[0], Theta[0], P, Q, c, alpha[0], s) + for i := 1; i < k; i++ { + good = good && thver(Xhat[i], Yhat[i], Theta[i], P, Q, + alpha[i-1], alpha[i], s) + } + for i := k; i < thlen; i++ { + good = good && thver(Gamma, G, Theta[i], P, Q, + alpha[i-1], alpha[i], s) + } + good = good && thver(Gamma, G, Theta[thlen], P, Q, + alpha[thlen-1], c, s) + if !good { + return errors.New("incorrect SimpleShuffleProof") + } + + return nil +} diff --git a/kyber/shuffle/vartime_test.go b/kyber/shuffle/vartime_test.go new file mode 100644 index 0000000000..f996a7fd13 --- /dev/null +++ b/kyber/shuffle/vartime_test.go @@ -0,0 +1,19 @@ +package shuffle + +import ( + "testing" + + "go.dedis.ch/kyber/v3/group/nist" +) + +func BenchmarkBiffleP256(b *testing.B) { + biffleTest(nist.NewBlakeSHA256P256(), b.N) +} + +func Benchmark2PairShuffleP256(b *testing.B) { + shuffleTest(nist.NewBlakeSHA256P256(), 2, b.N) +} + +func Benchmark10PairShuffleP256(b *testing.B) { + shuffleTest(nist.NewBlakeSHA256P256(), 10, b.N) +} diff --git a/kyber/sign/anon/anon.go b/kyber/sign/anon/anon.go new file mode 100644 index 0000000000..a22168b68b --- /dev/null +++ b/kyber/sign/anon/anon.go @@ -0,0 +1,10 @@ +// Package anon implements cryptographic primitives for anonymous communication. +package anon + +import ( + "go.dedis.ch/kyber/v3" +) + +// Set represents an explicit anonymity set +// as a list of public keys. +type Set []kyber.Point diff --git a/kyber/sign/anon/enc.go b/kyber/sign/anon/enc.go new file mode 100644 index 0000000000..dc1d4f6740 --- /dev/null +++ b/kyber/sign/anon/enc.go @@ -0,0 +1,187 @@ +package anon + +import ( + "crypto/subtle" + "errors" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/util/key" +) + +func header(suite Suite, X kyber.Point, x kyber.Scalar, + Xb, xb []byte, anonymitySet Set) []byte { + + //fmt.Printf("Xb %s\nxb %s\n", + // hex.EncodeToString(Xb),hex.EncodeToString(xb)) + + // Encrypt the master scalar key with each public key in the set + S := suite.Point() + hdr := Xb + for i := range anonymitySet { + Y := anonymitySet[i] + S.Mul(x, Y) // compute DH shared secret + seed, _ := S.MarshalBinary() + xof := suite.XOF(seed) + xc := make([]byte, len(xb)) + xof.XORKeyStream(xc, xb) + hdr = append(hdr, xc...) + } + return hdr +} + +// Create and encrypt a fresh key decryptable only by the given receivers. +// Returns the secret key and the ciphertext. +func encryptKey(suite Suite, anonymitySet Set) (k, c []byte) { + // Choose a keypair and encode its representation + kp := new(key.Pair) + var Xb []byte + kp.Gen(suite) + Xb, _ = kp.Public.MarshalBinary() + xb, _ := kp.Private.MarshalBinary() + // Generate the ciphertext header + return xb, header(suite, kp.Public, kp.Private, Xb, xb, anonymitySet) +} + +// Decrypt and verify a key encrypted via encryptKey. +// On success, returns the key and the length of the decrypted header. +func decryptKey(suite Suite, ciphertext []byte, anonymitySet Set, mine int, privateKey kyber.Scalar) ([]byte, int, error) { + // Decode the (supposed) ephemeral public key from the front + X := suite.Point() + var Xb []byte + enclen := X.MarshalSize() + if len(ciphertext) < enclen { + return nil, 0, errors.New("ciphertext too short") + } + if err := X.UnmarshalBinary(ciphertext[:enclen]); err != nil { + return nil, 0, err + } + Xb = ciphertext[:enclen] + Xblen := len(Xb) + + // Decode the (supposed) master secret with our private key + nkeys := len(anonymitySet) + if mine < 0 || mine >= nkeys { + panic("private-key index out of range") + } + seclen := suite.ScalarLen() + if len(ciphertext) < Xblen+seclen*nkeys { + return nil, 0, errors.New("ciphertext too short") + } + S := suite.Point().Mul(privateKey, X) + seed, _ := S.MarshalBinary() + xof := suite.XOF(seed) + xb := make([]byte, seclen) + secofs := Xblen + seclen*mine + xof.XORKeyStream(xb, ciphertext[secofs:secofs+seclen]) + x := suite.Scalar() + if err := x.UnmarshalBinary(xb); err != nil { + return nil, 0, err + } + + // Make sure it reproduces the correct ephemeral public key + Xv := suite.Point().Mul(x, nil) + if !X.Equal(Xv) { + return nil, 0, errors.New("invalid ciphertext") + } + + // Regenerate and check the rest of the header, + // to ensure that that any of the anonymitySet members could decrypt it + hdr := header(suite, X, x, Xb, xb, anonymitySet) + hdrlen := len(hdr) + if hdrlen != Xblen+seclen*nkeys { + panic("wrong header size") + } + if subtle.ConstantTimeCompare(hdr, ciphertext[:hdrlen]) == 0 { + return nil, 0, errors.New("invalid ciphertext") + } + + return xb, hdrlen, nil +} + +// constantTimeAllEq returns 1 iff all bytes in slice x have the value y. +// The time taken is a function of the length of the slices +// and is independent of the contents. +func constantTimeAllEq(x []byte, y byte) int { + var z byte + for _, b := range x { + z |= b ^ y + } + return subtle.ConstantTimeByteEq(z, 0) +} + +// macSize is how long the hashes are that we extract from the XOF. +// This constant of 16 is taken from the previous implementation's behavior. +const macSize = 16 + +// Encrypt a message for reading by any member of an explit anonymity set. +// The caller supplies one or more keys representing the anonymity set. +// If the provided set contains only one public key, +// this reduces to conventional single-receiver public-key encryption. +func Encrypt(suite Suite, message []byte, + anonymitySet Set) []byte { + + xb, hdr := encryptKey(suite, anonymitySet) + xof := suite.XOF(xb) + + // We now know the ciphertext layout + hdrhi := 0 + len(hdr) + msghi := hdrhi + len(message) + machi := msghi + macSize + ciphertext := make([]byte, machi) + copy(ciphertext, hdr) + + // Now encrypt and MAC the message based on the master secret + ctx := ciphertext[hdrhi:msghi] + mac := ciphertext[msghi:machi] + + xof.XORKeyStream(ctx, message) + xof = suite.XOF(ctx) + xof.Read(mac) + + return ciphertext +} + +// Decrypt a message encrypted for a particular anonymity set. +// Returns the cleartext message on success, or an error on failure. +// +// The caller provides the anonymity set for which the message is intended, +// and the private key corresponding to one of the public keys in the set. +// Decrypt verifies that the message is encrypted correctly for this set - +// in particular, that it could be decrypted by ALL of the listed members - +// before returning successfully with the decrypted message. +// +// This verification ensures that a malicious sender +// cannot de-anonymize a receiver by constructing a ciphertext incorrectly +// so as to be decryptable by only some members of the set. +// As a side-effect, this verification also ensures plaintext-awareness: +// that is, it is infeasible for a sender to construct any ciphertext +// that will be accepted by the receiver without knowing the plaintext. +// +func Decrypt(suite Suite, ciphertext []byte, anonymitySet Set, mine int, privateKey kyber.Scalar) ([]byte, error) { + // Decrypt and check the encrypted key-header. + xb, hdrlen, err := decryptKey(suite, ciphertext, anonymitySet, + mine, privateKey) + if err != nil { + return nil, err + } + + // Determine the message layout + xof := suite.XOF(xb) + if len(ciphertext) < hdrlen+macSize { + return nil, errors.New("ciphertext too short") + } + hdrhi := hdrlen + msghi := len(ciphertext) - macSize + + // Decrypt the message and check the MAC + ctx := ciphertext[hdrhi:msghi] + mac := ciphertext[msghi:] + msg := make([]byte, len(ctx)) + xof.XORKeyStream(msg, ctx) + xof = suite.XOF(ctx) + xof.XORKeyStream(mac, mac) + if constantTimeAllEq(mac, 0) == 0 { + return nil, errors.New("invalid ciphertext: failed MAC check") + } + return msg, nil +} diff --git a/kyber/sign/anon/enc_test.go b/kyber/sign/anon/enc_test.go new file mode 100644 index 0000000000..7c3fbe4fa2 --- /dev/null +++ b/kyber/sign/anon/enc_test.go @@ -0,0 +1,96 @@ +package anon + +import ( + "bytes" + "encoding/hex" + "fmt" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +func ExampleEncrypt_one() { + // Crypto setup: Get a suite which returns a predictable + // random number stream for this example. + // In production, simply use edwards25519.NewBlakeSHA256Ed25519() + suite := edwards25519.NewBlakeSHA256Ed25519WithRand(blake2xb.New(nil)) + + // Create a public/private keypair (X[mine],x) + X := make([]kyber.Point, 1) + mine := 0 // which public key is mine + x := suite.Scalar().Pick(suite.RandomStream()) // create a private key x + X[mine] = suite.Point().Mul(x, nil) // corresponding public key X + + // Encrypt a message with the public key + M := []byte("Hello World!") + C := Encrypt(suite, M, Set(X)) + fmt.Printf("Encryption of '%s':\n%s", string(M), hex.Dump(C)) + + // Decrypt the ciphertext with the private key + MM, err := Decrypt(suite, C, Set(X), mine, x) + if err != nil { + panic(err.Error()) + } + if !bytes.Equal(M, MM) { + panic("Decryption failed to reproduce message") + } + fmt.Printf("Decrypted: '%s'\n", string(MM)) + + // Output: + // Encryption of 'Hello World!': + // 00000000 82 ea 76 3b 11 5f ee b2 ac 08 62 af 84 52 1c 0c |..v;._....b..R..| + // 00000010 e9 1d 7d 15 b5 44 2e 65 cb 19 45 49 45 f0 10 8f |..}..D.e..EIE...| + // 00000020 7b c3 0c 03 22 67 9f 54 9a 44 52 a9 bb ac 51 07 |{..."g.T.DR...Q.| + // 00000030 c8 98 9d 5d dd 54 11 e3 9f a9 7c 44 b5 c7 bf f8 |...].T....|D....| + // 00000040 23 af 58 fb 5f 40 2d 92 e9 63 fe 71 13 33 e0 ce |#.X._@-..c.q.3..| + // 00000050 65 83 88 45 3c 88 3f bd 2f bd 3a 03 |e..E<.?./.:.| + // Decrypted: 'Hello World!' +} + +func ExampleEncrypt_anonSet() { + // Crypto setup: Get a suite which returns a predictable + // random number stream for this example. + // In production, simply use edwards25519.NewBlakeSHA256Ed25519() + suite := edwards25519.NewBlakeSHA256Ed25519WithRand(blake2xb.New(nil)) + + // Create an anonymity set of random "public keys" + X := make([]kyber.Point, 3) + for i := range X { // pick random points + X[i] = suite.Point().Pick(suite.RandomStream()) + } + + // Make just one of them an actual public/private keypair (X[mine],x) + mine := 1 // only the signer knows this + x := suite.Scalar().Pick(suite.RandomStream()) // create a private key x + X[mine] = suite.Point().Mul(x, nil) // corresponding public key X + + // Encrypt a message with all the public keys + M := []byte("Hello World!") // message to encrypt + C := Encrypt(suite, M, Set(X)) + fmt.Printf("Encryption of '%s':\n%s", string(M), hex.Dump(C)) + + // Decrypt the ciphertext with the known private key + MM, err := Decrypt(suite, C, Set(X), mine, x) + if err != nil { + panic(err.Error()) + } + if !bytes.Equal(M, MM) { + panic("Decryption failed to reproduce message") + } + fmt.Printf("Decrypted: '%s'\n", string(MM)) + + // Output: + // Encryption of 'Hello World!': + // 00000000 c3 c2 10 b2 dc 66 58 f7 6d 3b 65 a4 c6 b9 2a d5 |.....fX.m;e...*.| + // 00000010 3f 8d f8 68 41 92 c7 84 ef 7d a1 6c 59 89 d0 bc |?..hA....}.lY...| + // 00000020 ea 60 08 5f f4 ab 35 48 08 be 85 be e8 58 fa 84 |.`._..5H.....X..| + // 00000030 ea 97 d0 57 10 01 c4 bc 9f 65 18 a6 4c e1 d2 b9 |...W.....e..L...| + // 00000040 df 81 4a 63 da 92 56 49 20 f4 8a 9e ff d5 52 42 |..Jc..VI .....RB| + // 00000050 8d bd 28 b7 b3 61 3b 1c 89 12 cc 4b 8e d9 c0 7b |..(..a;....K...{| + // 00000060 7d f5 d8 53 c9 9f cf e9 cc 68 35 d3 e8 bc 21 b1 |}..S.....h5...!.| + // 00000070 01 7d ae b4 b0 eb 5b c0 ad b7 c7 b6 c5 9c 01 df |.}....[.........| + // 00000080 7c 35 28 21 1a 04 94 de ba 0f 42 6e b9 9f bb c5 ||5(!......Bn....| + // 00000090 1e 37 4d ab 06 63 d2 37 97 d5 45 2a |.7M..c.7..E*| + // Decrypted: 'Hello World!' +} diff --git a/kyber/sign/anon/sig.go b/kyber/sign/anon/sig.go new file mode 100644 index 0000000000..cd0a2e5945 --- /dev/null +++ b/kyber/sign/anon/sig.go @@ -0,0 +1,251 @@ +package anon + +import ( + "bytes" + "errors" + + "go.dedis.ch/kyber/v3" +) + +// unlinkable ring signature +type uSig struct { + C0 kyber.Scalar + S []kyber.Scalar +} + +// linkable ring signature +type lSig struct { + C0 kyber.Scalar + S []kyber.Scalar + Tag kyber.Point +} + +func signH1pre(suite Suite, linkScope []byte, linkTag kyber.Point, + message []byte) kyber.XOF { + H1pre := suite.XOF(message) // m + if linkScope != nil { + _, _ = H1pre.Write(linkScope) // L + tag, _ := linkTag.MarshalBinary() + _, _ = H1pre.Write(tag) // ~y + } + return H1pre +} + +func signH1(suite Suite, H1pre kyber.XOF, PG, PH kyber.Point) kyber.Scalar { + H1 := H1pre.Clone() + PGb, _ := PG.MarshalBinary() + _, _ = H1.Write(PGb) + if PH != nil { + PHb, _ := PH.MarshalBinary() + _, _ = H1.Write(PHb) + } + return suite.Scalar().Pick(H1) +} + +// Sign creates an optionally anonymous, optionally linkable +// signature on a given message. +// +// The caller supplies one or more public keys representing an anonymity set, +// and the private key corresponding to one of those public keys. +// The resulting signature proves to a verifier that the owner of +// one of these public keys signed the message, +// without revealing which key-holder signed the message, +// offering anonymity among the members of this explicit anonymity set. +// The other users whose keys are listed in the anonymity set need not consent +// or even be aware that they have been included in an anonymity set: +// anyone having a suitable public key may be "conscripted" into a set. +// +// If the provided anonymity set contains only one public key (the signer's), +// then this function produces a traditional non-anonymous signature, +// equivalent in both size and performance to a standard ElGamal signature. +// +// The caller may request either unlinkable or linkable anonymous signatures. +// If linkScope is nil, this function generates an unlinkable signature, +// which contains no information about which member signed the message. +// The anonymity provided by unlinkable signatures is forward-secure, +// in that a signature reveals nothing about which member generated it, +// even if all members' private keys are later released. +// For cryptographic background on unlinkable anonymity-set signatures - +// also known as ring signatures or ad-hoc group signatures - +// see Rivest, "How to Leak a Secret" at +// https://people.csail.mit.edu/rivest/pubs/RST01.pdf. +// +// If the caller passes a non-nil linkScope, +// the resulting anonymous signature will be linkable. +// This means that given two signatures produced using the same linkScope, +// a verifier will be able to tell whether +// the same or different anonymity set members produced those signatures. +// In particular, verifying a linkable signature yields a linkage tag. +// This linkage tag has a 1-to-1 correspondence with the signer's public key +// within a given linkScope, but is cryptographically unlinkable +// to either the signer's public key or to linkage tags in other scopes. +// The provided linkScope may be an arbitrary byte-string; +// the only significance these scopes have is whether they are equal or unequal. +// For details on the linkable signature algorithm this function implements, +// see Liu/Wei/Wong, +// "Linkable Spontaneous Anonymous Group Signature for Ad Hoc Groups" at +// https://eprint.iacr.org/2004/027. +// +// Linkage tags may be used to protect against sock-puppetry or Sybil attacks +// in situations where a verifier needs to know how many distinct members +// of an anonymity set are present or signed messages in a given context. +// It is cryptographically hard for one anonymity set member +// to produce signatures with different linkage tags in the same scope. +// An important and fundamental downside, however, is that +// linkable signatures do NOT offer forward-secure anonymity. +// If an anonymity set member's private key is later released, +// it is trivial to check whether or not that member produced a given signature. +// Also, anonymity set members who did NOT sign a message could +// (voluntarily or under coercion) prove that they did not sign it, +// e.g., simply by signing some other message in that linkage context +// and noting that the resulting linkage tag comes out different. +// Thus, linkable anonymous signatures are not appropriate to use +// in situations where there may be significant risk +// that members' private keys may later be compromised, +// or that members may be persuaded or coerced into revealing whether or not +// they produced a signature of interest. +// +func Sign(suite Suite, message []byte, + anonymitySet Set, linkScope []byte, mine int, privateKey kyber.Scalar) []byte { + + // Note that Rivest's original ring construction directly supports + // heterogeneous rings containing public keys of different types - + // e.g., a mixture of RSA keys and DSA keys with varying parameters. + // Our ring signature construction currently supports + // only homogeneous rings containing compatible keys + // drawn from the cipher suite (e.g., the same elliptic curve). + // The upside to this constrint is greater flexibility: + // e.g., we also easily obtain linkable ring signatures, + // which are not readily feasible with the original ring construction. + + n := len(anonymitySet) // anonymity set size + L := []kyber.Point(anonymitySet) // public keys in anonymity set + pi := mine + + // If we want a linkable ring signature, produce correct linkage tag, + // as a pseudorandom base point multiplied by our private key. + // Liu's scheme specifies the linkScope as a hash of the ring; + // this is one reasonable choice of linkage scope, + // but there are others, so we parameterize this choice. + var linkBase, linkTag kyber.Point + if linkScope != nil { + linkStream := suite.XOF(linkScope) + linkBase = suite.Point().Pick(linkStream) + linkTag = suite.Point().Mul(privateKey, linkBase) + } + + // First pre-hash the parameters to H1 + // that are invariant for different ring positions, + // so that we don't have to hash them many times. + H1pre := signH1pre(suite, linkScope, linkTag, message) + + // Pick a random commit for my ring position + u := suite.Scalar().Pick(suite.RandomStream()) + var UB, UL kyber.Point + UB = suite.Point().Mul(u, nil) + if linkScope != nil { + UL = suite.Point().Mul(u, linkBase) + } + + // Build the challenge ring + s := make([]kyber.Scalar, n) + c := make([]kyber.Scalar, n) + c[(pi+1)%n] = signH1(suite, H1pre, UB, UL) + var P, PG, PH kyber.Point + P = suite.Point() + PG = suite.Point() + if linkScope != nil { + PH = suite.Point() + } + for i := (pi + 1) % n; i != pi; i = (i + 1) % n { + s[i] = suite.Scalar().Pick(suite.RandomStream()) + PG.Add(PG.Mul(s[i], nil), P.Mul(c[i], L[i])) + if linkScope != nil { + PH.Add(PH.Mul(s[i], linkBase), P.Mul(c[i], linkTag)) + } + c[(i+1)%n] = signH1(suite, H1pre, PG, PH) + //fmt.Printf("s%d %s\n",i,s[i].String()) + //fmt.Printf("c%d %s\n",(i+1)%n,c[(i+1)%n].String()) + } + s[pi] = suite.Scalar() + s[pi].Mul(privateKey, c[pi]).Sub(u, s[pi]) // s_pi = u - x_pi c_pi + + // Encode and return the signature + buf := bytes.Buffer{} + if linkScope != nil { // linkable ring signature + sig := lSig{c[0], s, linkTag} + _ = suite.Write(&buf, &sig) + } else { // unlinkable ring signature + sig := uSig{c[0], s} + _ = suite.Write(&buf, &sig) + } + return buf.Bytes() +} + +// Verify checks a signature generated by Sign. +// +// The caller provides the message, anonymity set, and linkage scope +// with which the signature was purportedly produced. +// If the signature is a valid linkable signature (linkScope != nil), +// this function returns a linkage tag that uniquely corresponds +// to the signer within the given linkScope. +// If the signature is a valid unlinkable signature (linkScope == nil), +// Verify returns an empty but non-nil byte-slice instead of a linkage tag on success. +// Returns a nil linkage tag and an error if the signature is invalid. +func Verify(suite Suite, message []byte, anonymitySet Set, + linkScope []byte, signatureBuffer []byte) ([]byte, error) { + + n := len(anonymitySet) // anonymity set size + L := []kyber.Point(anonymitySet) // public keys in ring + + // Decode the signature + buf := bytes.NewBuffer(signatureBuffer) + var linkBase, linkTag kyber.Point + sig := lSig{} + sig.S = make([]kyber.Scalar, n) + if linkScope != nil { // linkable ring signature + if err := suite.Read(buf, &sig); err != nil { + return nil, err + } + linkStream := suite.XOF(linkScope) + linkBase = suite.Point().Pick(linkStream) + linkTag = sig.Tag + } else { // unlinkable ring signature + if err := suite.Read(buf, &sig.C0); err != nil { + return nil, err + } + if err := suite.Read(buf, &sig.S); err != nil { + return nil, err + } + } + + // Pre-hash the ring-position-invariant parameters to H1. + H1pre := signH1pre(suite, linkScope, linkTag, message) + + // Verify the signature + var P, PG, PH kyber.Point + P = suite.Point() + PG = suite.Point() + if linkScope != nil { + PH = suite.Point() + } + s := sig.S + ci := sig.C0 + for i := 0; i < n; i++ { + PG.Add(PG.Mul(s[i], nil), P.Mul(ci, L[i])) + if linkScope != nil { + PH.Add(PH.Mul(s[i], linkBase), P.Mul(ci, linkTag)) + } + ci = signH1(suite, H1pre, PG, PH) + } + if !ci.Equal(sig.C0) { + return nil, errors.New("invalid signature") + } + + // Return the re-encoded linkage tag, for uniqueness checking + if linkScope != nil { + tag, _ := linkTag.MarshalBinary() + return tag, nil + } + return []byte{}, nil +} diff --git a/kyber/sign/anon/sig_test.go b/kyber/sign/anon/sig_test.go new file mode 100644 index 0000000000..7b0ffce315 --- /dev/null +++ b/kyber/sign/anon/sig_test.go @@ -0,0 +1,313 @@ +package anon + +import ( + "bytes" + "encoding/hex" + "fmt" + "testing" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/util/random" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +// This example demonstrates signing and signature verification +// using a trivial "anonymity set" of size 1, i.e., no anonymity. +// In this special case the signing scheme devolves to +// producing traditional ElGamal signatures: +// the resulting signatures are exactly the same length +// and represent essentially the same computational cost. +func ExampleSign_one() { + // Crypto setup: Get a suite which returns a predictable + // random number stream for this example. + // In production, simply use edwards25519.NewBlakeSHA256Ed25519() + suite := edwards25519.NewBlakeSHA256Ed25519WithRand(blake2xb.New(nil)) + + // Create a public/private keypair (X[mine],x) + X := make([]kyber.Point, 1) + mine := 0 // which public key is mine + x := suite.Scalar().Pick(suite.RandomStream()) // create a private key x + X[mine] = suite.Point().Mul(x, nil) // corresponding public key X + + // Generate the signature + M := []byte("Hello World!") // message we want to sign + sig := Sign(suite, M, Set(X), nil, mine, x) + fmt.Print("Signature:\n" + hex.Dump(sig)) + + // Verify the signature against the correct message + tag, err := Verify(suite, M, Set(X), nil, sig) + if err != nil { + panic(err.Error()) + } + if tag == nil || len(tag) != 0 { + panic("Verify returned wrong tag") + } + fmt.Println("Signature verified against correct message.") + + // Verify the signature against the wrong message + BAD := []byte("Goodbye world!") + tag, err = Verify(suite, BAD, Set(X), nil, sig) + if err == nil || tag != nil { + panic("Signature verified against wrong message!?") + } + fmt.Println("Verifying against wrong message: " + err.Error()) + + // Output: + // Signature: + // 00000000 45 30 41 6a 51 d1 01 cf 7e ee 63 66 1d e9 e3 cf |E0AjQ...~.cf....| + // 00000010 a3 d2 1b 98 fc 46 99 6d 9f 91 cc 65 f4 9d 10 03 |.....F.m...e....| + // 00000020 45 a0 e0 5a bc fe 62 62 45 a9 e5 eb 00 e2 6b 66 |E..Z..bbE.....kf| + // 00000030 dc aa f0 53 7c 10 3e bf bd f6 30 8d 2d 2c 5c 0f |...S|.>...0.-,\.| + // Signature verified against correct message. + // Verifying against wrong message: invalid signature +} + +// This example demonstrates how to create unlinkable anonymity-set signatures, +// and to verify them, +// using a small anonymity set containing three public keys. +func ExampleSign_anonSet() { + // Crypto setup: Get a suite which returns a predictable + // random number stream for this example. + // In production, simply use edwards25519.NewBlakeSHA256Ed25519() + suite := edwards25519.NewBlakeSHA256Ed25519WithRand(blake2xb.New(nil)) + + // Create an anonymity set of random "public keys" + X := make([]kyber.Point, 3) + for i := range X { // pick random points + X[i] = suite.Point().Pick(suite.RandomStream()) + } + + // Make just one of them an actual public/private keypair (X[mine],x) + mine := 1 // only the signer knows this + x := suite.Scalar().Pick(suite.RandomStream()) // create a private key x + X[mine] = suite.Point().Mul(x, nil) // corresponding public key X + + // Generate the signature + M := []byte("Hello World!") // message we want to sign + sig := Sign(suite, M, Set(X), nil, mine, x) + fmt.Print("Signature:\n" + hex.Dump(sig)) + + // Verify the signature against the correct message + tag, err := Verify(suite, M, Set(X), nil, sig) + if err != nil { + panic(err.Error()) + } + if tag == nil || len(tag) != 0 { + panic("Verify returned wrong tag") + } + fmt.Println("Signature verified against correct message.") + + // Verify the signature against the wrong message + BAD := []byte("Goodbye world!") + tag, err = Verify(suite, BAD, Set(X), nil, sig) + if err == nil || tag != nil { + panic("Signature verified against wrong message!?") + } + fmt.Println("Verifying against wrong message: " + err.Error()) + + // Output: + // Signature: + // 00000000 dc 43 94 ce 5e c5 ab c1 f8 3e bd e1 30 a8 19 bd |.C..^....>..0...| + // 00000010 13 f7 b4 0d f0 f5 39 40 c3 de 71 26 f9 1c ba 0f |......9@..q&....| + // 00000020 61 f7 23 a0 e6 7c 95 b7 e4 b2 32 55 40 d4 25 87 |a.#..|....2U@.%.| + // 00000030 da d4 76 18 01 22 fb c7 93 f7 40 6b d6 e0 e7 0b |..v.."....@k....| + // 00000040 3d a3 1f 32 50 f8 c1 d2 c6 93 f4 19 e0 c7 2a 06 |=..2P.........*.| + // 00000050 ef 6f 1c 4d c9 4f 0e db c8 30 4d 20 94 52 e8 04 |.o.M.O...0M .R..| + // 00000060 f4 6d eb 7c 5f 30 09 60 bf c7 37 cd 44 16 fe bb |.m.|_0.`..7.D...| + // 00000070 b6 5a e5 45 b3 6c 7f b1 12 6d 60 b9 9f 60 0e 0c |.Z.E.l...m`..`..| + // Signature verified against correct message. + // Verifying against wrong message: invalid signature +} + +// This example demonstrates the creation of linkable anonymity set signatures, +// and verification, using an anonymity set containing three public keys. +// We produce four signatures, two from each of two private key-holders, +// demonstrating how the resulting verifiable tags distinguish +// signatures by the same key-holder from signatures by different key-holders. +func ExampleSign_linkable() { + // Crypto setup: Get a suite which returns a predictable + // random number stream for this example. + // In production, simply use edwards25519.NewBlakeSHA256Ed25519() + suite := edwards25519.NewBlakeSHA256Ed25519WithRand(blake2xb.New(nil)) + rand := suite.RandomStream() + + // Create an anonymity set of random "public keys" + X := make([]kyber.Point, 3) + for i := range X { // pick random points + X[i] = suite.Point().Pick(rand) + } + + // Make two actual public/private keypairs (X[mine],x) + mine1 := 1 // only the signer knows this + mine2 := 2 + x1 := suite.Scalar().Pick(rand) // create a private key x + x2 := suite.Scalar().Pick(rand) + X[mine1] = suite.Point().Mul(x1, nil) // corresponding public key X + X[mine2] = suite.Point().Mul(x2, nil) + + // Generate two signatures using x1 and two using x2 + M := []byte("Hello World!") // message we want to sign + S := []byte("My Linkage Scope") // scope for linkage tags + var sig [4][]byte + sig[0] = Sign(suite, M, Set(X), S, mine1, x1) + sig[1] = Sign(suite, M, Set(X), S, mine1, x1) + sig[2] = Sign(suite, M, Set(X), S, mine2, x2) + sig[3] = Sign(suite, M, Set(X), S, mine2, x2) + for i := range sig { + fmt.Printf("Signature %d:\n%s", i, hex.Dump(sig[i])) + } + + // Verify the signatures against the correct message + var tag [4][]byte + for i := range sig { + goodtag, err := Verify(suite, M, Set(X), S, sig[i]) + if err != nil { + panic(err.Error()) + } + tag[i] = goodtag + if tag[i] == nil || len(tag[i]) != suite.PointLen() { + panic("Verify returned invalid tag") + } + fmt.Printf("Sig%d tag: %s\n", i, + hex.EncodeToString(tag[i])) + + // Verify the signature against the wrong message + BAD := []byte("Goodbye world!") + badtag, err := Verify(suite, BAD, Set(X), S, sig[i]) + if err == nil || badtag != nil { + panic("Signature verified against wrong message!?") + } + } + if !bytes.Equal(tag[0], tag[1]) || !bytes.Equal(tag[2], tag[3]) || + bytes.Equal(tag[0], tag[2]) { + panic("tags aren't coming out right!") + } + + // Output: + // Signature 0: + // 00000000 a2 f1 f3 e3 07 35 6c a9 16 fb 4f c9 a7 35 c7 3b |.....5l...O..5.;| + // 00000010 7f 09 8b 70 45 8d 5f c1 2b 74 22 f2 bf 3d d1 0a |...pE._.+t"..=..| + // 00000020 4b 8b 88 78 28 d6 5f 77 d0 d6 1b 26 47 cb 7a 2e |K..x(._w...&G.z.| + // 00000030 3c f8 8c 4b 8b 39 cd 3e 92 e1 2c 2d ac 7f db 01 |<..K.9.>..,-....| + // 00000040 1b 1d c2 e4 1d fd 54 b9 29 b9 f1 ec 9c e1 bc c8 |......T.).......| + // 00000050 b5 db c8 9f 71 1c 48 1c 2c 02 b2 14 de e7 b6 08 |....q.H.,.......| + // 00000060 61 f7 23 a0 e6 7c 95 b7 e4 b2 32 55 40 d4 25 87 |a.#..|....2U@.%.| + // 00000070 da d4 76 18 01 22 fb c7 93 f7 40 6b d6 e0 e7 0b |..v.."....@k....| + // 00000080 da 86 5d 31 13 21 f5 95 70 d8 d7 a1 26 3b 47 dd |..]1.!..p...&;G.| + // 00000090 60 5d c2 1d 38 bf b7 49 e9 47 4a 8d 89 a4 b0 89 |`]..8..I.GJ.....| + // Signature 1: + // 00000000 14 b6 dd a5 99 0c e7 f7 d5 82 43 d5 45 84 19 7b |..........C.E..{| + // 00000010 db c6 3b f5 ee ce 01 50 17 57 58 21 37 31 25 0d |..;....P.WX!71%.| + // 00000020 81 b1 81 c3 f3 00 f9 0f 9d 58 58 5f 66 f4 52 75 |.........XX_f.Ru| + // 00000030 0f bb bc fc 25 58 f7 29 74 8a 57 79 93 75 d9 0b |....%X.)t.Wy.u..| + // 00000040 11 3d 25 cb be 39 0f 88 2c f8 ee 63 93 d8 98 94 |.=%..9..,..c....| + // 00000050 1b 85 fd 38 0a 37 87 0b c1 db a7 53 50 72 98 0c |...8.7.....SPr..| + // 00000060 7f 9a fb 37 f7 64 66 5c 7c b5 1f 2d b1 d5 63 67 |...7.df\|..-..cg| + // 00000070 12 1b d4 18 0a 5b 42 b2 c0 9e 3a 42 e2 c2 77 0c |.....[B...:B..w.| + // 00000080 da 86 5d 31 13 21 f5 95 70 d8 d7 a1 26 3b 47 dd |..]1.!..p...&;G.| + // 00000090 60 5d c2 1d 38 bf b7 49 e9 47 4a 8d 89 a4 b0 89 |`]..8..I.GJ.....| + // Signature 2: + // 00000000 5f 11 1a 2f 10 28 55 d9 e2 be 10 56 7e 57 37 ae |_../.(U....V~W7.| + // 00000010 7a a1 bc ec 87 0f 98 4f 52 cc 70 e6 14 79 8a 01 |z......OR.p..y..| + // 00000020 89 f7 f8 b6 91 d1 52 f7 f0 b2 3d 3c 70 f1 95 9e |......R...=.. .|...R.`.j| + // Signature 3: + // 00000000 a9 0f 3b 86 6f 4e c6 ea 8d e8 57 2c 1a 20 c6 14 |..;.oN....W,. ..| + // 00000010 5e 5b 66 95 0b 41 ce 57 94 a1 f0 36 73 cd c8 04 |^[f..A.W...6s...| + // 00000020 ff 47 7b f3 6e ee 9e 1f bb 0d 96 e7 b8 50 1d 9f |.G{.n........P..| + // 00000030 8f bf ea bc ef f3 d5 d9 9b 05 9b d3 5e c9 41 0e |............^.A.| + // 00000040 d1 e8 a3 f6 7b b4 8e 38 db 73 4a ef ca 9a 68 7b |....{..8.sJ...h{| + // 00000050 c3 d0 2a e3 a9 e5 c1 a3 b7 bb 60 92 75 f1 7e 00 |..*.......`.u.~.| + // 00000060 9a bd 63 f7 c0 cf 2d a1 4d 1e 2c 40 ff 11 d6 4f |..c...-.M.,@...O| + // 00000070 c5 a2 70 ab 14 2e 11 ee 24 e6 ca ca 15 e2 f7 0f |..p.....$.......| + // 00000080 49 d9 9a 38 a8 da c4 44 3d 6b 56 70 78 9e f0 01 |I..8...D=kVpx...| + // 00000090 c6 da 3e d2 ff 20 b0 7c 0e 88 c6 52 a1 60 f5 6a |..>.. .|...R.`.j| + // Sig0 tag: da865d311321f59570d8d7a1263b47dd605dc21d38bfb749e9474a8d89a4b089 + // Sig1 tag: da865d311321f59570d8d7a1263b47dd605dc21d38bfb749e9474a8d89a4b089 + // Sig2 tag: 49d99a38a8dac4443d6b5670789ef001c6da3ed2ff20b07c0e88c652a160f56a + // Sig3 tag: 49d99a38a8dac4443d6b5670789ef001c6da3ed2ff20b07c0e88c652a160f56a +} + +var benchMessage = []byte("Hello World!") + +var benchPubEd25519, benchPriEd25519 = benchGenKeysEd25519(100) +var benchSig1Ed25519 = benchGenSigEd25519(1) +var benchSig10Ed25519 = benchGenSigEd25519(10) +var benchSig100Ed25519 = benchGenSigEd25519(100) + +func benchGenKeys(g kyber.Group, + nkeys int) ([]kyber.Point, kyber.Scalar) { + rng := random.New() + + // Create an anonymity set of random "public keys" + X := make([]kyber.Point, nkeys) + for i := range X { // pick random points + X[i] = g.Point().Pick(rng) + } + + // Make just one of them an actual public/private keypair (X[mine],x) + x := g.Scalar().Pick(rng) + X[0] = g.Point().Mul(x, nil) + + return X, x +} + +func benchGenKeysEd25519(nkeys int) ([]kyber.Point, kyber.Scalar) { + return benchGenKeys(edwards25519.NewBlakeSHA256Ed25519(), nkeys) +} +func benchGenSigEd25519(nkeys int) []byte { + suite := edwards25519.NewBlakeSHA256Ed25519() + return Sign(suite, benchMessage, + Set(benchPubEd25519[:nkeys]), nil, + 0, benchPriEd25519) +} + +func benchSign(suite Suite, pub []kyber.Point, pri kyber.Scalar, + niter int) { + for i := 0; i < niter; i++ { + Sign(suite, benchMessage, Set(pub), nil, 0, pri) + } +} + +func benchVerify(suite Suite, pub []kyber.Point, + sig []byte, niter int) { + for i := 0; i < niter; i++ { + tag, err := Verify(suite, benchMessage, Set(pub), nil, sig) + if tag == nil || err != nil { + panic("benchVerify failed") + } + } +} + +func BenchmarkSign1Ed25519(b *testing.B) { + benchSign(edwards25519.NewBlakeSHA256Ed25519(), + benchPubEd25519[:1], benchPriEd25519, b.N) +} +func BenchmarkSign10Ed25519(b *testing.B) { + benchSign(edwards25519.NewBlakeSHA256Ed25519(), + benchPubEd25519[:10], benchPriEd25519, b.N) +} +func BenchmarkSign100Ed25519(b *testing.B) { + benchSign(edwards25519.NewBlakeSHA256Ed25519(), + benchPubEd25519[:100], benchPriEd25519, b.N) +} + +func BenchmarkVerify1Ed25519(b *testing.B) { + benchVerify(edwards25519.NewBlakeSHA256Ed25519(), + benchPubEd25519[:1], benchSig1Ed25519, b.N) +} +func BenchmarkVerify10Ed25519(b *testing.B) { + benchVerify(edwards25519.NewBlakeSHA256Ed25519(), + benchPubEd25519[:10], benchSig10Ed25519, b.N) +} +func BenchmarkVerify100Ed25519(b *testing.B) { + benchVerify(edwards25519.NewBlakeSHA256Ed25519(), + benchPubEd25519[:100], benchSig100Ed25519, b.N) +} diff --git a/kyber/sign/anon/suite.go b/kyber/sign/anon/suite.go new file mode 100644 index 0000000000..b840139413 --- /dev/null +++ b/kyber/sign/anon/suite.go @@ -0,0 +1,13 @@ +package anon + +import ( + "go.dedis.ch/kyber/v3" +) + +// Suite represents the set of functionalities needed by the package anon. +type Suite interface { + kyber.Group + kyber.Encoding + kyber.XOFFactory + kyber.Random +} diff --git a/kyber/sign/bls/bls.go b/kyber/sign/bls/bls.go new file mode 100644 index 0000000000..ed03a91b15 --- /dev/null +++ b/kyber/sign/bls/bls.go @@ -0,0 +1,138 @@ +// Package bls implements the Boneh-Lynn-Shacham (BLS) signature scheme which +// was introduced in the paper "Short Signatures from the Weil Pairing". BLS +// requires pairing-based cryptography. +package bls + +import ( + "crypto/cipher" + "crypto/sha256" + "errors" + "fmt" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/pairing" +) + +type hashablePoint interface { + Hash([]byte) kyber.Point +} + +// NewKeyPair creates a new BLS signing key pair. The private key x is a scalar +// and the public key X is a point on curve G2. +func NewKeyPair(suite pairing.Suite, random cipher.Stream) (kyber.Scalar, kyber.Point) { + x := suite.G2().Scalar().Pick(random) + X := suite.G2().Point().Mul(x, nil) + return x, X +} + +// Sign creates a BLS signature S = x * H(m) on a message m using the private +// key x. The signature S is a point on curve G1. +func Sign(suite pairing.Suite, x kyber.Scalar, msg []byte) ([]byte, error) { + hashable, ok := suite.G1().Point().(hashablePoint) + if !ok { + return nil, errors.New("point needs to implement hashablePoint") + } + HM := hashable.Hash(msg) + xHM := HM.Mul(x, HM) + s, err := xHM.MarshalBinary() + if err != nil { + return nil, err + } + return s, nil +} + +// AggregateSignatures combines signatures created using the Sign function +func AggregateSignatures(suite pairing.Suite, sigs ...[]byte) ([]byte, error) { + sig := suite.G1().Point() + for _, sigBytes := range sigs { + sigToAdd := suite.G1().Point() + if err := sigToAdd.UnmarshalBinary(sigBytes); err != nil { + return nil, err + } + sig.Add(sig, sigToAdd) + } + return sig.MarshalBinary() +} + +// AggregatePublicKeys takes a slice of public G2 points and returns +// the sum of those points. This is used to verify multisignatures. +func AggregatePublicKeys(suite pairing.Suite, Xs ...kyber.Point) kyber.Point { + aggregated := suite.G2().Point() + for _, X := range Xs { + aggregated.Add(aggregated, X) + } + return aggregated +} + +// BatchVerify verifies a large number of publicKey/msg pairings with a single aggregated signature. +// Since aggregation is generally much faster than verification, this can be a speed enhancement. +// Benchmarks show a roughly 50% performance increase over individual signature verification +// Every msg must be unique or there is the possibility to accept an invalid signature +// see: https://crypto.stackexchange.com/questions/56288/is-bls-signature-scheme-strongly-unforgeable/56290 +// for a description of why each message must be unique. +func BatchVerify(suite pairing.Suite, publics []kyber.Point, msgs [][]byte, sig []byte) error { + if !distinct(msgs) { + return fmt.Errorf("bls: error, messages must be distinct") + } + + s := suite.G1().Point() + if err := s.UnmarshalBinary(sig); err != nil { + return err + } + + var aggregatedLeft kyber.Point + for i := range msgs { + hashable, ok := suite.G1().Point().(hashablePoint) + if !ok { + return errors.New("bls: point needs to implement hashablePoint") + } + hm := hashable.Hash(msgs[i]) + pair := suite.Pair(hm, publics[i]) + + if i == 0 { + aggregatedLeft = pair + } else { + aggregatedLeft.Add(aggregatedLeft, pair) + } + } + + right := suite.Pair(s, suite.G2().Point().Base()) + if !aggregatedLeft.Equal(right) { + return errors.New("bls: invalid signature") + } + return nil +} + +// Verify checks the given BLS signature S on the message m using the public +// key X by verifying that the equality e(H(m), X) == e(H(m), x*B2) == +// e(x*H(m), B2) == e(S, B2) holds where e is the pairing operation and B2 is +// the base point from curve G2. +func Verify(suite pairing.Suite, X kyber.Point, msg, sig []byte) error { + hashable, ok := suite.G1().Point().(hashablePoint) + if !ok { + return errors.New("bls: point needs to implement hashablePoint") + } + HM := hashable.Hash(msg) + left := suite.Pair(HM, X) + s := suite.G1().Point() + if err := s.UnmarshalBinary(sig); err != nil { + return err + } + right := suite.Pair(s, suite.G2().Point().Base()) + if !left.Equal(right) { + return errors.New("bls: invalid signature") + } + return nil +} + +func distinct(msgs [][]byte) bool { + m := make(map[[32]byte]bool) + for _, msg := range msgs { + h := sha256.Sum256(msg) + if m[h] { + return false + } + m[h] = true + } + return true +} diff --git a/kyber/sign/bls/bls_test.go b/kyber/sign/bls/bls_test.go new file mode 100644 index 0000000000..88ca54c6f0 --- /dev/null +++ b/kyber/sign/bls/bls_test.go @@ -0,0 +1,227 @@ +package bls + +import ( + "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/pairing/bn256" + "go.dedis.ch/kyber/v3/util/random" +) + +func TestBLS(t *testing.T) { + msg := []byte("Hello Boneh-Lynn-Shacham") + suite := bn256.NewSuite() + private, public := NewKeyPair(suite, random.New()) + sig, err := Sign(suite, private, msg) + require.Nil(t, err) + err = Verify(suite, public, msg, sig) + require.Nil(t, err) +} + +func TestBLSFailSig(t *testing.T) { + msg := []byte("Hello Boneh-Lynn-Shacham") + suite := bn256.NewSuite() + private, public := NewKeyPair(suite, random.New()) + sig, err := Sign(suite, private, msg) + require.Nil(t, err) + sig[0] ^= 0x01 + if Verify(suite, public, msg, sig) == nil { + t.Fatal("bls: verification succeeded unexpectedly") + } +} + +func TestBLSFailKey(t *testing.T) { + msg := []byte("Hello Boneh-Lynn-Shacham") + suite := bn256.NewSuite() + private, _ := NewKeyPair(suite, random.New()) + sig, err := Sign(suite, private, msg) + require.Nil(t, err) + _, public := NewKeyPair(suite, random.New()) + if Verify(suite, public, msg, sig) == nil { + t.Fatal("bls: verification succeeded unexpectedly") + } +} + +func TestBLSAggregateSignatures(t *testing.T) { + msg := []byte("Hello Boneh-Lynn-Shacham") + suite := bn256.NewSuite() + private1, public1 := NewKeyPair(suite, random.New()) + private2, public2 := NewKeyPair(suite, random.New()) + sig1, err := Sign(suite, private1, msg) + require.Nil(t, err) + sig2, err := Sign(suite, private2, msg) + require.Nil(t, err) + aggregatedSig, err := AggregateSignatures(suite, sig1, sig2) + require.Nil(t, err) + + aggregatedKey := AggregatePublicKeys(suite, public1, public2) + + err = Verify(suite, aggregatedKey, msg, aggregatedSig) + require.Nil(t, err) +} + +func TestBLSFailAggregatedSig(t *testing.T) { + msg := []byte("Hello Boneh-Lynn-Shacham") + suite := bn256.NewSuite() + private1, public1 := NewKeyPair(suite, random.New()) + private2, public2 := NewKeyPair(suite, random.New()) + sig1, err := Sign(suite, private1, msg) + require.Nil(t, err) + sig2, err := Sign(suite, private2, msg) + require.Nil(t, err) + aggregatedSig, err := AggregateSignatures(suite, sig1, sig2) + require.Nil(t, err) + aggregatedKey := AggregatePublicKeys(suite, public1, public2) + + aggregatedSig[0] ^= 0x01 + if Verify(suite, aggregatedKey, msg, aggregatedSig) == nil { + t.Fatal("bls: verification succeeded unexpectedly") + } +} +func TestBLSFailAggregatedKey(t *testing.T) { + msg := []byte("Hello Boneh-Lynn-Shacham") + suite := bn256.NewSuite() + private1, public1 := NewKeyPair(suite, random.New()) + private2, public2 := NewKeyPair(suite, random.New()) + _, public3 := NewKeyPair(suite, random.New()) + sig1, err := Sign(suite, private1, msg) + require.Nil(t, err) + sig2, err := Sign(suite, private2, msg) + require.Nil(t, err) + aggregatedSig, err := AggregateSignatures(suite, sig1, sig2) + require.Nil(t, err) + badAggregatedKey := AggregatePublicKeys(suite, public1, public2, public3) + + if Verify(suite, badAggregatedKey, msg, aggregatedSig) == nil { + t.Fatal("bls: verification succeeded unexpectedly") + } +} +func TestBLSBatchVerify(t *testing.T) { + msg1 := []byte("Hello Boneh-Lynn-Shacham") + msg2 := []byte("Hello Dedis & Boneh-Lynn-Shacham") + suite := bn256.NewSuite() + private1, public1 := NewKeyPair(suite, random.New()) + private2, public2 := NewKeyPair(suite, random.New()) + sig1, err := Sign(suite, private1, msg1) + require.Nil(t, err) + sig2, err := Sign(suite, private2, msg2) + require.Nil(t, err) + aggregatedSig, err := AggregateSignatures(suite, sig1, sig2) + require.Nil(t, err) + + err = BatchVerify(suite, []kyber.Point{public1, public2}, [][]byte{msg1, msg2}, aggregatedSig) + require.Nil(t, err) +} +func TestBLSFailBatchVerify(t *testing.T) { + msg1 := []byte("Hello Boneh-Lynn-Shacham") + msg2 := []byte("Hello Dedis & Boneh-Lynn-Shacham") + suite := bn256.NewSuite() + private1, public1 := NewKeyPair(suite, random.New()) + private2, public2 := NewKeyPair(suite, random.New()) + sig1, err := Sign(suite, private1, msg1) + require.Nil(t, err) + sig2, err := Sign(suite, private2, msg2) + require.Nil(t, err) + + t.Run("fails with a bad signature", func(t *testing.T) { + aggregatedSig, err := AggregateSignatures(suite, sig1, sig2) + require.Nil(t, err) + msg2[0] ^= 0x01 + if BatchVerify(suite, []kyber.Point{public1, public2}, [][]byte{msg1, msg2}, aggregatedSig) == nil { + t.Fatal("bls: verification succeeded unexpectedly") + } + }) + + t.Run("fails with a duplicate msg", func(t *testing.T) { + private3, public3 := NewKeyPair(suite, random.New()) + sig3, err := Sign(suite, private3, msg1) + require.Nil(t, err) + aggregatedSig, err := AggregateSignatures(suite, sig1, sig2, sig3) + require.Nil(t, err) + + if BatchVerify(suite, []kyber.Point{public1, public2, public3}, [][]byte{msg1, msg2, msg1}, aggregatedSig) == nil { + t.Fatal("bls: verification succeeded unexpectedly") + } + }) + +} + +func BenchmarkBLSKeyCreation(b *testing.B) { + suite := bn256.NewSuite() + b.ResetTimer() + for i := 0; i < b.N; i++ { + NewKeyPair(suite, random.New()) + } +} + +func BenchmarkBLSSign(b *testing.B) { + suite := bn256.NewSuite() + private, _ := NewKeyPair(suite, random.New()) + msg := []byte("Hello many times Boneh-Lynn-Shacham") + b.ResetTimer() + for i := 0; i < b.N; i++ { + Sign(suite, private, msg) + } +} + +func BenchmarkBLSAggregateSigs(b *testing.B) { + suite := bn256.NewSuite() + private1, _ := NewKeyPair(suite, random.New()) + private2, _ := NewKeyPair(suite, random.New()) + msg := []byte("Hello many times Boneh-Lynn-Shacham") + sig1, err := Sign(suite, private1, msg) + require.Nil(b, err) + sig2, err := Sign(suite, private2, msg) + require.Nil(b, err) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + AggregateSignatures(suite, sig1, sig2) + } +} + +func BenchmarkBLSVerifyAggregate(b *testing.B) { + suite := bn256.NewSuite() + private1, public1 := NewKeyPair(suite, random.New()) + private2, public2 := NewKeyPair(suite, random.New()) + msg := []byte("Hello many times Boneh-Lynn-Shacham") + sig1, err := Sign(suite, private1, msg) + require.Nil(b, err) + sig2, err := Sign(suite, private2, msg) + require.Nil(b, err) + sig, err := AggregateSignatures(suite, sig1, sig2) + key := AggregatePublicKeys(suite, public1, public2) + b.ResetTimer() + for i := 0; i < b.N; i++ { + Verify(suite, key, msg, sig) + } +} + +func BenchmarkBLSVerifyBatchVerify(b *testing.B) { + suite := bn256.NewSuite() + + numSigs := 100 + privates := make([]kyber.Scalar, numSigs) + publics := make([]kyber.Point, numSigs) + msgs := make([][]byte, numSigs) + sigs := make([][]byte, numSigs) + for i := 0; i < numSigs; i++ { + private, public := NewKeyPair(suite, random.New()) + privates[i] = private + publics[i] = public + msg := make([]byte, 64, 64) + rand.Read(msg) + msgs[i] = msg + sig, err := Sign(suite, private, msg) + require.Nil(b, err) + sigs[i] = sig + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + aggregateSig, _ := AggregateSignatures(suite, sigs...) + BatchVerify(suite, publics, msgs, aggregateSig) + } +} diff --git a/kyber/sign/cosi/cosi.go b/kyber/sign/cosi/cosi.go new file mode 100644 index 0000000000..dbb38e78e3 --- /dev/null +++ b/kyber/sign/cosi/cosi.go @@ -0,0 +1,405 @@ +/* +Package cosi implements the collective signing (CoSi) algorithm as presented in +the paper "Keeping Authorities 'Honest or Bust' with Decentralized Witness +Cosigning" by Ewa Syta et al. See https://arxiv.org/abs/1503.08768. This +package only provides the functionality for the cryptographic operations of +CoSi. All network-related operations have to be handled elsewhere. Below we +describe a high-level overview of the CoSi protocol (using a star communication +topology). We refer to the research paper for further details on communication +over trees, exception mechanisms and signature verification policies. + +The CoSi protocol has four phases executed between a list of participants P +having a protocol leader (index i = 0) and a list of other nodes (index i > 0). +The secret key of node i is denoted by a_i and the public key by A_i = [a_i]G +(where G is the base point of the underlying group and [...] denotes scalar +multiplication). The aggregate public key is given as A = \sum{i ∈ P}(A_i). + +1. Announcement: The leader broadcasts an announcement to the other nodes +optionally including the message M to be signed. Upon receiving an announcement +message, a node starts its commitment phase. + +2. Commitment: Each node i (including the leader) picks a random scalar v_i, +computes its commitment V_i = [v_i]G and sends V_i back to the leader. The +leader waits until it has received enough commitments (according to some +policy) from the other nodes or a timer has run out. Let P' be the nodes that +have sent their commitments. The leader computes an aggregate commitment V from +all commitments he has received, i.e., V = \sum{j ∈ P'}(V_j) and creates a +participation bitmask Z. The leader then broadcasts V and Z to the other +participations together with the message M if it was not sent in phase 1. Upon +receiving a commitment message, a node starts the challenge phase. + +3. Challenge: Each node i computes the collective challenge c = H(V || A || M) +using a cryptographic hash function H (here: SHA512), computes its +response r_i = v_i + c*a_i and sends it back to the leader. + +4. Response: The leader waits until he has received replies from all nodes in +P' or a timer has run out. If he has not enough replies he aborts. Finally, +the leader computes the aggregate response r = \sum{j ∈ P'}(r_j) and publishes +(V,r,Z) as the signature for the message M. +*/ +package cosi + +import ( + "errors" + "fmt" + + "go.dedis.ch/kyber/v3" +) + +// Commit returns a random scalar v, generated from the given suite, +// and a corresponding commitment V = [v]G. If the given cipher stream is nil, +// a random stream is used. +func Commit(suite Suite) (v kyber.Scalar, V kyber.Point) { + random := suite.Scalar().Pick(suite.RandomStream()) + commitment := suite.Point().Mul(random, nil) + return random, commitment +} + +// AggregateCommitments returns the sum of the given commitments and the +// bitwise OR of the corresponding masks. +func AggregateCommitments(suite Suite, commitments []kyber.Point, masks [][]byte) (sum kyber.Point, commits []byte, err error) { + if len(commitments) != len(masks) { + return nil, nil, errors.New("mismatching lengths of commitment and mask slices") + } + aggCom := suite.Point().Null() + aggMask := make([]byte, len(masks[0])) + + for i := range commitments { + aggCom = suite.Point().Add(aggCom, commitments[i]) + aggMask, err = AggregateMasks(aggMask, masks[i]) + if err != nil { + return nil, nil, err + } + } + return aggCom, aggMask, nil +} + +// Challenge creates the collective challenge from the given aggregate +// commitment V, aggregate public key A, and message M, i.e., it returns +// c = H(V || A || M). +func Challenge(suite Suite, commitment, public kyber.Point, message []byte) (kyber.Scalar, error) { + if commitment == nil { + return nil, errors.New("no commitment provided") + } + if message == nil { + return nil, errors.New("no message provided") + } + hash := suite.Hash() + if _, err := commitment.MarshalTo(hash); err != nil { + return nil, err + } + if _, err := public.MarshalTo(hash); err != nil { + return nil, err + } + hash.Write(message) + return suite.Scalar().SetBytes(hash.Sum(nil)), nil +} + +// Response creates the response from the given random scalar v, (collective) +// challenge c, and private key a, i.e., it returns r = v + c*a. +func Response(suite Suite, private, random, challenge kyber.Scalar) (kyber.Scalar, error) { + if private == nil { + return nil, errors.New("no private key provided") + } + if random == nil { + return nil, errors.New("no random scalar provided") + } + if challenge == nil { + return nil, errors.New("no challenge provided") + } + ca := suite.Scalar().Mul(private, challenge) + return ca.Add(random, ca), nil +} + +// AggregateResponses returns the sum of given responses. +func AggregateResponses(suite Suite, responses []kyber.Scalar) (kyber.Scalar, error) { + if responses == nil { + return nil, errors.New("no responses provided") + } + r := suite.Scalar().Zero() + for i := range responses { + r = r.Add(r, responses[i]) + } + return r, nil +} + +// Sign returns the collective signature from the given (aggregate) commitment +// V, (aggregate) response r, and participation bitmask Z using the EdDSA +// format, i.e., the signature is V || r || Z. +func Sign(suite Suite, commitment kyber.Point, response kyber.Scalar, mask *Mask) ([]byte, error) { + if commitment == nil { + return nil, errors.New("no commitment provided") + } + if response == nil { + return nil, errors.New("no response provided") + } + if mask == nil { + return nil, errors.New("no mask provided") + } + lenV := suite.PointLen() + lenSig := lenV + suite.ScalarLen() + VB, err := commitment.MarshalBinary() + if err != nil { + return nil, errors.New("marshalling of commitment failed") + } + RB, err := response.MarshalBinary() + if err != nil { + return nil, errors.New("marshalling of signature failed") + } + sig := make([]byte, lenSig+mask.Len()) + copy(sig[:], VB) + copy(sig[lenV:lenSig], RB) + copy(sig[lenSig:], mask.mask) + return sig, nil +} + +// Verify checks the given cosignature on the provided message using the list +// of public keys and cosigning policy. +func Verify(suite Suite, publics []kyber.Point, message, sig []byte, policy Policy) error { + if publics == nil { + return errors.New("no public keys provided") + } + if message == nil { + return errors.New("no message provided") + } + if sig == nil { + return errors.New("no signature provided") + } + if policy == nil { + policy = CompletePolicy{} + } + + lenCom := suite.PointLen() + if len(sig) < lenCom { + return errors.New("signature too short") + } + VBuff := sig[:lenCom] + V := suite.Point() + if err := V.UnmarshalBinary(VBuff); err != nil { + return errors.New("unmarshalling of commitment failed") + } + + // Unpack the aggregate response + lenRes := lenCom + suite.ScalarLen() + if len(sig) < lenRes { + return errors.New("signature too short") + } + rBuff := sig[lenCom:lenRes] + r := suite.Scalar().SetBytes(rBuff) + + // Unpack the participation mask and get the aggregate public key + mask, err := NewMask(suite, publics, nil) + if err != nil { + return err + } + mask.SetMask(sig[lenRes:]) + A := mask.AggregatePublic + ABuff, err := A.MarshalBinary() + if err != nil { + return errors.New("marshalling of aggregate public key failed") + } + + // Recompute the challenge + hash := suite.Hash() + hash.Write(VBuff) + hash.Write(ABuff) + hash.Write(message) + buff := hash.Sum(nil) + k := suite.Scalar().SetBytes(buff) + + // k * -aggPublic + s * B = k*-A + s*B + // from s = k * a + r => s * B = k * a * B + r * B <=> s*B = k*A + r*B + // <=> s*B + k*-A = r*B + minusPublic := suite.Point().Neg(A) + kA := suite.Point().Mul(k, minusPublic) + sB := suite.Point().Mul(r, nil) + left := suite.Point().Add(kA, sB) + + if !left.Equal(V) { + return errors.New("recreated response is different from signature") + } + if !policy.Check(mask) { + return errors.New("the policy is not fulfilled") + } + + return nil +} + +// Mask represents a cosigning participation bitmask. +type Mask struct { + mask []byte + publics []kyber.Point + AggregatePublic kyber.Point +} + +// NewMask returns a new participation bitmask for cosigning where all +// cosigners are disabled by default. If a public key is given it verifies that +// it is present in the list of keys and sets the corresponding index in the +// bitmask to 1 (enabled). +func NewMask(suite Suite, publics []kyber.Point, myKey kyber.Point) (*Mask, error) { + m := &Mask{ + publics: publics, + } + m.mask = make([]byte, m.Len()) + m.AggregatePublic = suite.Point().Null() + if myKey != nil { + found := false + for i, key := range publics { + if key.Equal(myKey) { + m.SetBit(i, true) + found = true + break + } + } + if !found { + return nil, errors.New("key not found") + } + } + return m, nil +} + +// Mask returns a copy of the participation bitmask. +func (m *Mask) Mask() []byte { + clone := make([]byte, len(m.mask)) + copy(clone[:], m.mask) + return clone +} + +// Len returns the mask length in bytes. +func (m *Mask) Len() int { + return (len(m.publics) + 7) >> 3 +} + +// SetMask sets the participation bitmask according to the given byte slice +// interpreted in little-endian order, i.e., bits 0-7 of byte 0 correspond to +// cosigners 0-7, bits 0-7 of byte 1 correspond to cosigners 8-15, etc. +func (m *Mask) SetMask(mask []byte) error { + if m.Len() != len(mask) { + return fmt.Errorf("mismatching mask lengths") + } + for i := range m.publics { + byt := i >> 3 + msk := byte(1) << uint(i&7) + if ((m.mask[byt] & msk) == 0) && ((mask[byt] & msk) != 0) { + m.mask[byt] ^= msk // flip bit in mask from 0 to 1 + m.AggregatePublic.Add(m.AggregatePublic, m.publics[i]) + } + if ((m.mask[byt] & msk) != 0) && ((mask[byt] & msk) == 0) { + m.mask[byt] ^= msk // flip bit in mask from 1 to 0 + m.AggregatePublic.Sub(m.AggregatePublic, m.publics[i]) + } + } + return nil +} + +// SetBit enables (enable: true) or disables (enable: false) the bit +// in the participation mask of the given cosigner. +func (m *Mask) SetBit(i int, enable bool) error { + if i >= len(m.publics) { + return errors.New("index out of range") + } + byt := i >> 3 + msk := byte(1) << uint(i&7) + if ((m.mask[byt] & msk) == 0) && enable { + m.mask[byt] ^= msk // flip bit in mask from 0 to 1 + m.AggregatePublic.Add(m.AggregatePublic, m.publics[i]) + } + if ((m.mask[byt] & msk) != 0) && !enable { + m.mask[byt] ^= msk // flip bit in mask from 1 to 0 + m.AggregatePublic.Sub(m.AggregatePublic, m.publics[i]) + } + return nil +} + +// IndexEnabled checks whether the given index is enabled in the mask or not. +func (m *Mask) IndexEnabled(i int) (bool, error) { + if i >= len(m.publics) { + return false, errors.New("index out of range") + } + byt := i >> 3 + msk := byte(1) << uint(i&7) + return ((m.mask[byt] & msk) != 0), nil +} + +// KeyEnabled checks whether the index, corresponding to the given key, is +// enabled in the mask or not. +func (m *Mask) KeyEnabled(public kyber.Point) (bool, error) { + for i, key := range m.publics { + if key.Equal(public) { + return m.IndexEnabled(i) + } + } + return false, errors.New("key not found") +} + +// CountEnabled returns the number of enabled nodes in the CoSi participation +// mask. +func (m *Mask) CountEnabled() int { + // hw is hamming weight + hw := 0 + for i := range m.publics { + byt := i >> 3 + msk := byte(1) << uint(i&7) + if (m.mask[byt] & msk) != 0 { + hw++ + } + } + return hw +} + +// CountTotal returns the total number of nodes this CoSi instance knows. +func (m *Mask) CountTotal() int { + return len(m.publics) +} + +// AggregateMasks computes the bitwise OR of the two given participation masks. +func AggregateMasks(a, b []byte) ([]byte, error) { + if len(a) != len(b) { + return nil, errors.New("mismatching mask lengths") + } + m := make([]byte, len(a)) + for i := range m { + m[i] = a[i] | b[i] + } + return m, nil +} + +// Policy represents a fully customizable cosigning policy deciding what +// cosigner sets are and aren't sufficient for a collective signature to be +// considered acceptable to a verifier. The Check method may inspect the set of +// participants that cosigned by invoking cosi.Mask and/or cosi.MaskBit, and may +// use any other relevant contextual information (e.g., how security-critical +// the operation relying on the collective signature is) in determining whether +// the collective signature was produced by an acceptable set of cosigners. +type Policy interface { + Check(m *Mask) bool +} + +// CompletePolicy is the default policy requiring that all participants have +// cosigned to make a collective signature valid. +type CompletePolicy struct { +} + +// Check verifies that all participants have contributed to a collective +// signature. +func (p CompletePolicy) Check(m *Mask) bool { + return m.CountEnabled() == m.CountTotal() +} + +// ThresholdPolicy allows to specify a simple t-of-n policy requring that at +// least the given threshold number of participants t have cosigned to make a +// collective signature valid. +type ThresholdPolicy struct { + thold int +} + +// NewThresholdPolicy returns a new ThresholdPolicy with the given threshold. +func NewThresholdPolicy(thold int) *ThresholdPolicy { + return &ThresholdPolicy{thold: thold} +} + +// Check verifies that at least a threshold number of participants have +// contributed to a collective signature. +func (p ThresholdPolicy) Check(m *Mask) bool { + return m.CountEnabled() >= p.thold +} diff --git a/kyber/sign/cosi/cosi_test.go b/kyber/sign/cosi/cosi_test.go new file mode 100644 index 0000000000..437e11e984 --- /dev/null +++ b/kyber/sign/cosi/cosi_test.go @@ -0,0 +1,190 @@ +package cosi + +import ( + "crypto/cipher" + "crypto/sha512" + "errors" + "hash" + "testing" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/sign/eddsa" + "go.dedis.ch/kyber/v3/util/key" + "go.dedis.ch/kyber/v3/xof/blake2xb" +) + +// Specify cipher suite using AES-128, SHA512, and the Edwards25519 curve. +type cosiSuite struct { + Suite + r kyber.XOF +} + +func (m *cosiSuite) Hash() hash.Hash { + return sha512.New() +} +func (m *cosiSuite) RandomStream() cipher.Stream { return m.r } + +var testSuite = &cosiSuite{edwards25519.NewBlakeSHA256Ed25519(), blake2xb.New(nil)} + +func TestCoSi(t *testing.T) { + testCoSi(t, 2, 0) + testCoSi(t, 5, 0) + testCoSi(t, 5, 2) + testCoSi(t, 5, 4) +} + +func testCoSi(t *testing.T, n, f int) { + message := []byte("Hello World Cosi") + + // Generate key pairs + var kps []*key.Pair + var privates []kyber.Scalar + var publics []kyber.Point + for i := 0; i < n; i++ { + kp := key.NewKeyPair(testSuite) + kps = append(kps, kp) + privates = append(privates, kp.Private) + publics = append(publics, kp.Public) + } + + // Init masks + var masks []*Mask + var byteMasks [][]byte + for i := 0; i < n-f; i++ { + m, err := NewMask(testSuite, publics, publics[i]) + if err != nil { + t.Fatal(err) + } + masks = append(masks, m) + byteMasks = append(byteMasks, masks[i].Mask()) + } + + // Compute commitments + var v []kyber.Scalar // random + var V []kyber.Point // commitment + for i := 0; i < n-f; i++ { + x, X := Commit(testSuite) + v = append(v, x) + V = append(V, X) + } + + // Aggregate commitments + aggV, aggMask, err := AggregateCommitments(testSuite, V, byteMasks) + if err != nil { + t.Fatal(err) + } + + // Set aggregate mask in nodes + for i := 0; i < n-f; i++ { + masks[i].SetMask(aggMask) + } + + // Compute challenge + var c []kyber.Scalar + for i := 0; i < n-f; i++ { + ci, err := Challenge(testSuite, aggV, masks[i].AggregatePublic, message) + if err != nil { + t.Fatal(err) + } + c = append(c, ci) + } + + // Compute responses + var r []kyber.Scalar + for i := 0; i < n-f; i++ { + ri, _ := Response(testSuite, privates[i], v[i], c[i]) + r = append(r, ri) + } + + // Aggregate responses + aggr, err := AggregateResponses(testSuite, r) + if err != nil { + t.Fatal(err) + } + + for i := 0; i < n-f; i++ { + // Sign + sig, err := Sign(testSuite, aggV, aggr, masks[i]) + if err != nil { + t.Fatal(err) + } + // Set policy depending on threshold f and then Verify + var p Policy + if f == 0 { + p = nil + } else { + p = NewThresholdPolicy(n - f) + } + // send a short sig in, expect an error + if err := Verify(testSuite, publics, message, sig[0:10], p); err == nil { + t.Fatal("expected error on short sig") + } + if err := Verify(testSuite, publics, message, sig, p); err != nil { + t.Fatal(err) + } + // cosi signature should follow the same format as EdDSA except it has no mask + maskLen := len(masks[i].Mask()) + if err := eddsa.Verify(masks[i].AggregatePublic, message, sig[0:len(sig)-maskLen]); err != nil { + t.Fatal(err) + } + } +} + +func TestMask(t *testing.T) { + n := 17 + + // Generate key pairs + var kps []*key.Pair + var privates []kyber.Scalar + var publics []kyber.Point + for i := 0; i < n; i++ { + kp := key.NewKeyPair(testSuite) + kps = append(kps, kp) + privates = append(privates, kp.Private) + publics = append(publics, kp.Public) + } + + // Init masks and aggregate them + var masks []*Mask + var aggr []byte + for i := 0; i < n; i++ { + m, err := NewMask(testSuite, publics, publics[i]) + if err != nil { + t.Fatal(err) + } + masks = append(masks, m) + + if i == 0 { + aggr = masks[i].Mask() + } else { + aggr, err = AggregateMasks(aggr, masks[i].Mask()) + if err != nil { + t.Fatal(err) + } + } + } + + // Set and check aggregate mask + if err := masks[0].SetMask(aggr); err != nil { + t.Fatal(err) + } + + if masks[0].CountEnabled() != n { + t.Fatal(errors.New("unexpected number of active indices")) + } + + if _, err := masks[0].KeyEnabled(masks[0].AggregatePublic); err == nil { + t.Fatal(err) + } + + for i := 0; i < n; i++ { + b, err := masks[0].KeyEnabled(publics[i]) + if err != nil { + t.Fatal(err) + } + if !b { + t.Fatal(errors.New("mask bit not properly set")) + } + } +} diff --git a/kyber/sign/cosi/suite.go b/kyber/sign/cosi/suite.go new file mode 100644 index 0000000000..91529379bf --- /dev/null +++ b/kyber/sign/cosi/suite.go @@ -0,0 +1,10 @@ +package cosi + +import "go.dedis.ch/kyber/v3" + +// Suite specifies the cryptographic building blocks required for the cosi package. +type Suite interface { + kyber.Group + kyber.HashFactory + kyber.Random +} diff --git a/kyber/sign/dss/dss.go b/kyber/sign/dss/dss.go new file mode 100644 index 0000000000..4a899d5b7c --- /dev/null +++ b/kyber/sign/dss/dss.go @@ -0,0 +1,245 @@ +// Package dss implements the Distributed Schnorr Signature protocol from the +// paper "Provably Secure Distributed Schnorr Signatures and a (t, n) +// Threshold Scheme for Implicit Certificates". +// https://dl.acm.org/citation.cfm?id=678297 +// To generate a distributed signature from a group of participants, the group +// must first generate one longterm distributed secret with the share/dkg +// package, and then one random secret to be used only once. +// Each participant then creates a DSS struct, that can issue partial signatures +// with `dss.PartialSignature()`. These partial signatures can be broadcasted to +// the whole group or to a trusted combiner. Once one has collected enough +// partial signatures, it is possible to compute the distributed signature with +// the `Signature` method. +// The resulting signature is compatible with the EdDSA verification function. +// against the longterm distributed key. +package dss + +import ( + "bytes" + "crypto/sha512" + "errors" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/share" + "go.dedis.ch/kyber/v3/sign/eddsa" + "go.dedis.ch/kyber/v3/sign/schnorr" +) + +// Suite represents the functionalities needed by the dss package +type Suite interface { + kyber.Group + kyber.HashFactory + kyber.Random +} + +// DistKeyShare is an abstraction to allow one to use distributed key share +// from different schemes easily into this distributed threshold Schnorr +// signature framework. +type DistKeyShare interface { + PriShare() *share.PriShare + Commitments() []kyber.Point +} + +// DSS holds the information used to issue partial signatures as well as to +// compute the distributed schnorr signature. +type DSS struct { + suite Suite + secret kyber.Scalar + public kyber.Point + index int + participants []kyber.Point + T int + long DistKeyShare + random DistKeyShare + longPoly *share.PubPoly + randomPoly *share.PubPoly + msg []byte + partials []*share.PriShare + partialsIdx map[int]bool + signed bool + sessionID []byte +} + +// PartialSig is partial representation of the final distributed signature. It +// must be sent to each of the other participants. +type PartialSig struct { + Partial *share.PriShare + SessionID []byte + Signature []byte +} + +// NewDSS returns a DSS struct out of the suite, the longterm secret of this +// node, the list of participants, the longterm and random distributed key +// (generated by the dkg package), the message to sign and finally the T +// threshold. It returns an error if the public key of the secret can't be found +// in the list of participants. +func NewDSS(suite Suite, secret kyber.Scalar, participants []kyber.Point, + long, random DistKeyShare, msg []byte, T int) (*DSS, error) { + public := suite.Point().Mul(secret, nil) + var i int + var found bool + for j, p := range participants { + if p.Equal(public) { + found = true + i = j + break + } + } + if !found { + return nil, errors.New("dss: public key not found in list of participants") + } + return &DSS{ + suite: suite, + secret: secret, + public: public, + index: i, + participants: participants, + long: long, + longPoly: share.NewPubPoly(suite, suite.Point().Base(), long.Commitments()), + random: random, + randomPoly: share.NewPubPoly(suite, suite.Point().Base(), random.Commitments()), + msg: msg, + T: T, + partialsIdx: make(map[int]bool), + sessionID: sessionID(suite, long, random), + }, nil +} + +// PartialSig generates the partial signature related to this DSS. This +// PartialSig can be broadcasted to every other participant or only to a +// trusted combiner as described in the paper. +// The signature format is compatible with EdDSA verification implementations. +func (d *DSS) PartialSig() (*PartialSig, error) { + // following the notations from the paper + alpha := d.long.PriShare().V + beta := d.random.PriShare().V + hash := d.hashSig() + right := d.suite.Scalar().Mul(hash, alpha) + ps := &PartialSig{ + Partial: &share.PriShare{ + V: right.Add(right, beta), + I: d.index, + }, + SessionID: d.sessionID, + } + var err error + ps.Signature, err = schnorr.Sign(d.suite, d.secret, ps.Hash(d.suite)) + if !d.signed { + d.partialsIdx[d.index] = true + d.partials = append(d.partials, ps.Partial) + d.signed = true + } + return ps, err +} + +// ProcessPartialSig takes a PartialSig from another participant and stores it +// for generating the distributed signature. It returns an error if the index is +// wrong, or the signature is invalid or if a partial signature has already been +// received by the same peer. To know whether the distributed signature can be +// computed after this call, one can use the `EnoughPartialSigs` method. +func (d *DSS) ProcessPartialSig(ps *PartialSig) error { + public, ok := findPub(d.participants, ps.Partial.I) + if !ok { + return errors.New("dss: partial signature with invalid index") + } + + if err := schnorr.Verify(d.suite, public, ps.Hash(d.suite), ps.Signature); err != nil { + return err + } + + // nothing secret here + if !bytes.Equal(ps.SessionID, d.sessionID) { + return errors.New("dss: session id do not match") + } + + if _, ok := d.partialsIdx[ps.Partial.I]; ok { + return errors.New("dss: partial signature already received from peer") + } + + hash := d.hashSig() + idx := ps.Partial.I + randShare := d.randomPoly.Eval(idx) + longShare := d.longPoly.Eval(idx) + right := d.suite.Point().Mul(hash, longShare.V) + right.Add(randShare.V, right) + left := d.suite.Point().Mul(ps.Partial.V, nil) + if !left.Equal(right) { + return errors.New("dss: partial signature not valid") + } + d.partialsIdx[ps.Partial.I] = true + d.partials = append(d.partials, ps.Partial) + return nil +} + +// EnoughPartialSig returns true if there are enough partial signature to compute +// the distributed signature. It returns false otherwise. If there are enough +// partial signatures, one can issue the signature with `Signature()`. +func (d *DSS) EnoughPartialSig() bool { + return len(d.partials) >= d.T +} + +// Signature computes the distributed signature from the list of partial +// signatures received. It returns an error if there are not enough partial +// signatures. The signature is compatible with the EdDSA verification +// alrogithm. +func (d *DSS) Signature() ([]byte, error) { + if !d.EnoughPartialSig() { + return nil, errors.New("dkg: not enough partial signatures to sign") + } + gamma, err := share.RecoverSecret(d.suite, d.partials, d.T, len(d.participants)) + if err != nil { + return nil, err + } + // RandomPublic || gamma + var buff bytes.Buffer + _, _ = d.random.Commitments()[0].MarshalTo(&buff) + _, _ = gamma.MarshalTo(&buff) + return buff.Bytes(), nil +} + +func (d *DSS) hashSig() kyber.Scalar { + // H(R || A || msg) with + // * R = distributed random "key" + // * A = distributed public key + // * msg = msg to sign + h := sha512.New() + _, _ = d.random.Commitments()[0].MarshalTo(h) + _, _ = d.long.Commitments()[0].MarshalTo(h) + _, _ = h.Write(d.msg) + return d.suite.Scalar().SetBytes(h.Sum(nil)) +} + +// Verify takes a public key, a message and a signature and returns an error if +// the signature is invalid. +func Verify(public kyber.Point, msg, sig []byte) error { + return eddsa.Verify(public, msg, sig) +} + +// Hash returns the hash representation of this PartialSig to be used in a +// signature. +func (ps *PartialSig) Hash(s Suite) []byte { + h := s.Hash() + _, _ = h.Write(ps.Partial.Hash(s)) + _, _ = h.Write(ps.SessionID) + return h.Sum(nil) +} + +func findPub(list []kyber.Point, i int) (kyber.Point, bool) { + if i >= len(list) { + return nil, false + } + return list[i], true +} + +func sessionID(s Suite, a, b DistKeyShare) []byte { + h := s.Hash() + for _, p := range a.Commitments() { + _, _ = p.MarshalTo(h) + } + + for _, p := range b.Commitments() { + _, _ = p.MarshalTo(h) + } + + return h.Sum(nil) +} diff --git a/kyber/sign/dss/dss_test.go b/kyber/sign/dss/dss_test.go new file mode 100644 index 0000000000..4dc891a13b --- /dev/null +++ b/kyber/sign/dss/dss_test.go @@ -0,0 +1,225 @@ +package dss + +import ( + "crypto/rand" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + dkg "go.dedis.ch/kyber/v3/share/dkg/rabin" + "go.dedis.ch/kyber/v3/sign/eddsa" + "go.dedis.ch/kyber/v3/sign/schnorr" +) + +var suite = edwards25519.NewBlakeSHA256Ed25519() + +var nbParticipants = 7 +var t = nbParticipants/2 + 1 + +var partPubs []kyber.Point +var partSec []kyber.Scalar + +var longterms []*dkg.DistKeyShare +var randoms []*dkg.DistKeyShare + +var dss []*DSS + +func init() { + partPubs = make([]kyber.Point, nbParticipants) + partSec = make([]kyber.Scalar, nbParticipants) + for i := 0; i < nbParticipants; i++ { + sec, pub := genPair() + partPubs[i] = pub + partSec[i] = sec + } + longterms = genDistSecret() + randoms = genDistSecret() +} + +func TestDSSNew(t *testing.T) { + dss, err := NewDSS(suite, partSec[0], partPubs, longterms[0], randoms[0], []byte("hello"), 4) + assert.NotNil(t, dss) + assert.Nil(t, err) + + dss, err = NewDSS(suite, suite.Scalar().Zero(), partPubs, longterms[0], randoms[0], []byte("hello"), 4) + assert.Nil(t, dss) + assert.Error(t, err) +} + +func TestDSSPartialSigs(t *testing.T) { + dss0 := getDSS(0) + dss1 := getDSS(1) + ps0, err := dss0.PartialSig() + assert.Nil(t, err) + assert.NotNil(t, ps0) + assert.Len(t, dss0.partials, 1) + // second time should not affect list + ps0, err = dss0.PartialSig() + assert.Nil(t, err) + assert.NotNil(t, ps0) + assert.Len(t, dss0.partials, 1) + + // wrong index + goodI := ps0.Partial.I + ps0.Partial.I = 100 + assert.Error(t, dss1.ProcessPartialSig(ps0)) + ps0.Partial.I = goodI + + // wrong Signature + goodSig := ps0.Signature + ps0.Signature = randomBytes(len(ps0.Signature)) + assert.Error(t, dss1.ProcessPartialSig(ps0)) + ps0.Signature = goodSig + + // invalid partial sig + goodV := ps0.Partial.V + ps0.Partial.V = suite.Scalar().Zero() + ps0.Signature, err = schnorr.Sign(suite, dss0.secret, ps0.Hash(suite)) + require.Nil(t, err) + err = dss1.ProcessPartialSig(ps0) + assert.Error(t, err) + assert.Contains(t, err.Error(), "not valid") + ps0.Partial.V = goodV + ps0.Signature = goodSig + + // fine + err = dss1.ProcessPartialSig(ps0) + assert.Nil(t, err) + + // already received + assert.Error(t, dss1.ProcessPartialSig(ps0)) + + // if not enough partial signatures, can't generate signature + buff, err := dss1.Signature() + assert.Nil(t, buff) + assert.Error(t, err) + assert.Contains(t, err.Error(), "not enough") + + // enough partial sigs ? + for i := 2; i < nbParticipants; i++ { + dss := getDSS(i) + ps, err := dss.PartialSig() + require.Nil(t, err) + require.Nil(t, dss1.ProcessPartialSig(ps)) + } + assert.True(t, dss1.EnoughPartialSig()) +} + +func TestDSSSignature(t *testing.T) { + dsss := make([]*DSS, nbParticipants) + pss := make([]*PartialSig, nbParticipants) + for i := 0; i < nbParticipants; i++ { + dsss[i] = getDSS(i) + ps, err := dsss[i].PartialSig() + require.Nil(t, err) + require.NotNil(t, ps) + pss[i] = ps + } + for i, dss := range dsss { + for j, ps := range pss { + if i == j { + continue + } + require.Nil(t, dss.ProcessPartialSig(ps)) + } + } + // issue and verify signature + dss0 := dsss[0] + buff, err := dss0.Signature() + assert.NotNil(t, buff) + assert.Nil(t, err) + err = eddsa.Verify(longterms[0].Public(), dss0.msg, buff) + assert.Nil(t, err) + assert.Nil(t, Verify(longterms[0].Public(), dss0.msg, buff)) +} + +func getDSS(i int) *DSS { + dss, err := NewDSS(suite, partSec[i], partPubs, longterms[i], randoms[i], []byte("hello"), t) + if dss == nil || err != nil { + panic("nil dss") + } + return dss +} + +func genDistSecret() []*dkg.DistKeyShare { + dkgs := make([]*dkg.DistKeyGenerator, nbParticipants) + for i := 0; i < nbParticipants; i++ { + dkg, err := dkg.NewDistKeyGenerator(suite, partSec[i], partPubs, nbParticipants/2+1) + if err != nil { + panic(err) + } + dkgs[i] = dkg + } + // full secret sharing exchange + // 1. broadcast deals + resps := make([]*dkg.Response, 0, nbParticipants*nbParticipants) + for _, dkg := range dkgs { + deals, err := dkg.Deals() + if err != nil { + panic(err) + } + for i, d := range deals { + resp, err := dkgs[i].ProcessDeal(d) + if err != nil { + panic(err) + } + if !resp.Response.Approved { + panic("wrong approval") + } + resps = append(resps, resp) + } + } + // 2. Broadcast responses + for _, resp := range resps { + for h, dkg := range dkgs { + // ignore all messages from ourself + if resp.Response.Index == uint32(h) { + continue + } + j, err := dkg.ProcessResponse(resp) + if err != nil || j != nil { + panic("wrongProcessResponse") + } + } + } + // 4. Broadcast secret commitment + for i, dkg := range dkgs { + scs, err := dkg.SecretCommits() + if err != nil { + panic("wrong SecretCommits") + } + for j, dkg2 := range dkgs { + if i == j { + continue + } + cc, err := dkg2.ProcessSecretCommits(scs) + if err != nil || cc != nil { + panic("wrong ProcessSecretCommits") + } + } + } + + // 5. reveal shares + dkss := make([]*dkg.DistKeyShare, len(dkgs)) + for i, dkg := range dkgs { + dks, err := dkg.DistKeyShare() + if err != nil { + panic(err) + } + dkss[i] = dks + } + return dkss + +} +func genPair() (kyber.Scalar, kyber.Point) { + sc := suite.Scalar().Pick(suite.RandomStream()) + return sc, suite.Point().Mul(sc, nil) +} + +func randomBytes(n int) []byte { + var buff = make([]byte, n) + _, _ = rand.Read(buff[:]) + return buff +} diff --git a/kyber/sign/eddsa/eddsa.go b/kyber/sign/eddsa/eddsa.go new file mode 100644 index 0000000000..cfeeb78fc4 --- /dev/null +++ b/kyber/sign/eddsa/eddsa.go @@ -0,0 +1,171 @@ +// Package eddsa implements the EdDSA signature algorithm according to +// RFC8032. +package eddsa + +import ( + "crypto/cipher" + "crypto/sha512" + "errors" + "fmt" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/util/random" +) + +var group = new(edwards25519.Curve) + +// EdDSA is a structure holding the data necessary to make a series of +// EdDSA signatures. +type EdDSA struct { + // Secret being already hashed + bit tweaked + Secret kyber.Scalar + // Public is the corresponding public key + Public kyber.Point + + seed []byte + prefix []byte +} + +// NewEdDSA will return a freshly generated key pair to use for generating +// EdDSA signatures. +func NewEdDSA(stream cipher.Stream) *EdDSA { + if stream == nil { + panic("stream is required") + } + var buffer [32]byte + random.Bytes(buffer[:], stream) + + scalar := hashSeed(buffer[:]) + + secret := group.Scalar().SetBytes(scalar[:32]) + public := group.Point().Mul(secret, nil) + + return &EdDSA{ + seed: buffer[:], + prefix: scalar[32:], + Secret: secret, + Public: public, + } +} + +// MarshalBinary will return the representation used by the reference +// implementation of SUPERCOP ref10, which is "seed || Public". +func (e *EdDSA) MarshalBinary() ([]byte, error) { + pBuff, err := e.Public.MarshalBinary() + if err != nil { + return nil, err + } + + eddsa := make([]byte, 64) + copy(eddsa, e.seed) + copy(eddsa[32:], pBuff) + return eddsa, nil +} + +// UnmarshalBinary transforms a slice of bytes into a EdDSA signature. +func (e *EdDSA) UnmarshalBinary(buff []byte) error { + if len(buff) != 64 { + return errors.New("wrong length for decoding EdDSA private") + } + + e.seed = buff[:32] + scalar := hashSeed(e.seed) + e.prefix = scalar[32:] + e.Secret = group.Scalar().SetBytes(scalar[:32]) + e.Public = group.Point().Mul(e.Secret, nil) + return nil +} + +// Sign will return a EdDSA signature of the message msg using Ed25519. +func (e *EdDSA) Sign(msg []byte) ([]byte, error) { + hash := sha512.New() + _, _ = hash.Write(e.prefix) + _, _ = hash.Write(msg) + + // deterministic random secret and its commit + r := group.Scalar().SetBytes(hash.Sum(nil)) + R := group.Point().Mul(r, nil) + + // challenge + // H( R || Public || Msg) + hash.Reset() + Rbuff, err := R.MarshalBinary() + if err != nil { + return nil, err + } + Abuff, err := e.Public.MarshalBinary() + if err != nil { + return nil, err + } + + _, _ = hash.Write(Rbuff) + _, _ = hash.Write(Abuff) + _, _ = hash.Write(msg) + + h := group.Scalar().SetBytes(hash.Sum(nil)) + + // response + // s = r + h * s + s := group.Scalar().Mul(e.Secret, h) + s.Add(r, s) + + sBuff, err := s.MarshalBinary() + if err != nil { + return nil, err + } + + // return R || s + var sig [64]byte + copy(sig[:], Rbuff) + copy(sig[32:], sBuff) + + return sig[:], nil +} + +// Verify uses a public key, a message and a signature. It will return nil if +// sig is a valid signature for msg created by key public, or an error otherwise. +func Verify(public kyber.Point, msg, sig []byte) error { + if len(sig) != 64 { + return fmt.Errorf("signature length invalid, expect 64 but got %v", len(sig)) + } + + R := group.Point() + if err := R.UnmarshalBinary(sig[:32]); err != nil { + return fmt.Errorf("got R invalid point: %s", err) + } + + s := group.Scalar() + if err := s.UnmarshalBinary(sig[32:]); err != nil { + return fmt.Errorf("schnorr: s invalid scalar %s", err) + } + + // reconstruct h = H(R || Public || Msg) + Pbuff, err := public.MarshalBinary() + if err != nil { + return err + } + hash := sha512.New() + _, _ = hash.Write(sig[:32]) + _, _ = hash.Write(Pbuff) + _, _ = hash.Write(msg) + + h := group.Scalar().SetBytes(hash.Sum(nil)) + // reconstruct S == k*A + R + S := group.Point().Mul(s, nil) + hA := group.Point().Mul(h, public) + RhA := group.Point().Add(R, hA) + + if !RhA.Equal(S) { + return errors.New("reconstructed S is not equal to signature") + } + return nil +} + +func hashSeed(seed []byte) (hash [64]byte) { + hash = sha512.Sum512(seed) + hash[0] &= 0xf8 + hash[31] &= 0x3f + hash[31] |= 0x40 + return +} diff --git a/kyber/sign/eddsa/eddsa_test.go b/kyber/sign/eddsa/eddsa_test.go new file mode 100644 index 0000000000..bacf2c68f9 --- /dev/null +++ b/kyber/sign/eddsa/eddsa_test.go @@ -0,0 +1,181 @@ +package eddsa + +import ( + "bufio" + "bytes" + "compress/gzip" + "crypto/cipher" + "encoding/hex" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +// EdDSATestVectors taken from RFC8032 section 7.1 +var EdDSATestVectors = []struct { + private string + public string + message string + signature string +}{ + {"9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a", + "", + "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"}, + {"4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", + "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", + "72", + "92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00"}, + {"c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7", + "fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025", + "af82", + "6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a"}, + {"f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5", + "278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e", + "08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0", + "0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03"}, + {"833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42", + "ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf", + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", + "dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704"}, +} + +// Tests if marshalling and unmarshalling an EdDSA signature gives us the same +// signature +func TestEdDSAMarshalling(t *testing.T) { + for _, vec := range EdDSATestVectors { + seed, err := hex.DecodeString(vec.private) + assert.Nil(t, err) + + stream := ConstantStream(seed) + edDSA := NewEdDSA(stream) + marshalled, err := edDSA.MarshalBinary() + assert.Nil(t, err) + assert.NotNil(t, marshalled) + + unmarshalled := &EdDSA{} + err = unmarshalled.UnmarshalBinary(marshalled) + assert.Nil(t, err) + assert.Equal(t, edDSA, unmarshalled) + } +} + +// Comparing our implementation with the test vectors of the RFC +func TestEdDSASigning(t *testing.T) { + for i, vec := range EdDSATestVectors { + seed, err := hex.DecodeString(vec.private) + assert.Nil(t, err) + if len(vec.private) != 64 || len(seed) != 32 { + t.Fatal("len vec.private") + } + + stream := ConstantStream(seed) + + ed := NewEdDSA(stream) + + data, _ := ed.Public.MarshalBinary() + if hex.EncodeToString(data) != vec.public { + t.Error("Public not equal") + } + if len(vec.public) != 64 { + t.Fatal("len vec.private") + } + + msg, _ := hex.DecodeString(vec.message) + + sig, err := ed.Sign(msg) + assert.Nil(t, err) + + if hex.EncodeToString(sig) != vec.signature { + t.Error("Test", i, "Signature wrong", hex.EncodeToString(sig), vec.signature) + } + assert.Nil(t, Verify(ed.Public, msg, sig)) + } +} + +type constantStream struct { + seed []byte +} + +// ConstantStream is a cipher.Stream which always returns +// the same value. +func ConstantStream(buff []byte) cipher.Stream { + return &constantStream{buff} +} + +// XORKexStream implements the cipher.Stream interface +func (cs *constantStream) XORKeyStream(dst, src []byte) { + copy(dst, cs.seed) +} + +// Adapted from golang.org/x/crypto/ed25519. +func TestGolden(t *testing.T) { + // sign.input.gz is a selection of test cases from + // https://ed25519.cr.yp.to/python/sign.input + testDataZ, err := os.Open("testdata/sign.input.gz") + if err != nil { + t.Fatal(err) + } + defer testDataZ.Close() + testData, err := gzip.NewReader(testDataZ) + if err != nil { + t.Fatal(err) + } + defer testData.Close() + + scanner := bufio.NewScanner(testData) + lineNo := 0 + + const SignatureSize = 64 + const PublicKeySize = 32 + const PrivateKeySize = 32 + + for scanner.Scan() { + lineNo++ + + line := scanner.Text() + parts := strings.Split(line, ":") + if len(parts) != 5 { + t.Fatalf("bad number of parts on line %d", lineNo) + } + + privBytes, _ := hex.DecodeString(parts[0]) + pubKey, _ := hex.DecodeString(parts[1]) + msg, _ := hex.DecodeString(parts[2]) + sig, _ := hex.DecodeString(parts[3]) + // The signatures in the test vectors also include the message + // at the end, but we just want R and S. + sig = sig[:SignatureSize] + + if l := len(pubKey); l != PublicKeySize { + t.Fatalf("bad public key length on line %d: got %d bytes", lineNo, l) + } + + var priv [PrivateKeySize]byte + copy(priv[:], privBytes) + copy(priv[32:], pubKey) + + stream := ConstantStream(privBytes) + ed := NewEdDSA(stream) + + data, _ := ed.Public.MarshalBinary() + if !bytes.Equal(data, pubKey) { + t.Error("Public not equal") + } + + sig2, err := ed.Sign(msg) + assert.Nil(t, err) + + if !bytes.Equal(sig, sig2[:]) { + t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2) + } + + assert.Nil(t, Verify(ed.Public, msg, sig2)) + } + + if err := scanner.Err(); err != nil { + t.Fatalf("error reading test data: %s", err) + } +} diff --git a/kyber/sign/eddsa/testdata/sign.input.gz b/kyber/sign/eddsa/testdata/sign.input.gz new file mode 100644 index 0000000000000000000000000000000000000000..6c30678638135ccb05b78468d46fceb296220a4a GIT binary patch literal 784638 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Ê|KGwuuk;E?HF+bryXWIVoOgbTVQX8Q zs=;*a{P+2!{dN*LxFj{B&#bS>=;o zkA4WgtVI5BbPbZ~$Vc<)NStdz5(#c$EPet!z`n)DiboR^bm#UOf>w+(YI1E~FFZj9 z_j#4%$*iu^pi;AT&$y4$3lOgy*$e&HFwiY3-27^=qs4^@e6jVM=sNf5w^b`bL;X7u z|9v9<5PVMc6tOb~#EhmX$c{ZeO*0xcagTdkWr}Q54lfV)-;;L&2SA)Z<%AIUmU&i) zAVWkNf3EjR!QPAve+9e~x{{6`VslQ=bb00o|H&p;Y`qj>lQFK0%F%wlhO>V1csam~RCbVZOS6vVUX-{4tZjXmc zd2BMe+JCGBMudo~IfUAtDk0zF*^kY&*0q9|R06kieyfEI*FL(kT;sX*nE(OE`2l{} zVFk|(qzOXfB<8Lstp~CVUEvkC+R;kif4b@Yb5VVJ`^kJaHWu+UN7sOk#3QksG^=GZ zDYg=_waxKtmzCAGY(mA?OSO&DGxO>l-4Zk@YJ3&OJkx9Z1tw$MEsCztpQ1$pt5`mj z7)aY4{!YbzpNc=t{t0%-(z=2GVK(nZqhs#(8hhz_t`(_rgN&37sMeTU!>B0^e|_LL zZVwHWa7Aq~|E zuOZ5jTIjX+*o6hqCpZ&BFGNBWlzO&ZPayx@Pk+Aa5`Akb&>`{z(VC~bKOavE`k=9( z@3`RE4+;Kc>B;k5A77$V{1W-nXY1PM_b73znHEvqlS)-3#>&_1uxPrZn$ZPxvTaBqwlf!t1^YhMme;5FPXcYBp@BMb~ku`I2heR1(1DCd&`H}s`pI<*<*elU<*L1ZMLL06g5kZtKeDegM)Y+N?g$kW~}(RIeQy=st)O zYy+_RP|s?9U7vt>modCOR0W&u>6x$90#6BA*(ivY(+)Z(lRC!fyawaxmFHBElG$ou zex=Zl7a|09kPggsXz#N7I*J#O6?pPz&I~4bJvcZ(s*wSR+Af9X(=NKZYEbs59K)k| z4JZd=0OIuA!Xk%PC)U5y@&B5RKXEtvt{C=MZ2PQgsH)OaKZii zGH5U|-q_1NVl@a?o#@VgK(wGvzGVevFkh`KTVU3!EGH0zAt1m5p;&8nvj&S`7F<~| zi3ZId7AvcW0Mk>`?s~(2J;!ob!!5QjUppM5VBbY+%@b+jFwO+(&!T1TsfTE_XvM-Q zsLZPndsnW-9?B0FpZ;0dqyz}EFX17)7jFsEC(TY^HNvwB`>VI94jMo}PxjtV-RtKm z4}`mTutktE#xv_NT7E}Xx+Pg1z~%KA@C1xlL&lq5DaFE>7j9400;3!L`g-joZtE+y zv5CXNu=0$F;sEx|U$3sPscd%1cD5odtf+Wmo+l+-Fs`IzD|QO%T<3$p>E z=g-qLDs#b$zhm$xA0uax=!ZQa=m2gO&lqi}dt$G_bD~U%v_6;+-n5R9Jt@mUg*YJ3 zdta@r;~gusWT~6yO+Qx?%bgTCm@N6nbk)-&I%6O!e za#Gx-EBYtfCFolRJ>Tz@lNECSui@z-OG!=d_&lVt-8Gv1J0<_)l>8B}+JZRM8anPH zfw|Ur!9Eq`wk#!y`AkjOHeW(pkEFYn)_MmB;Jstr{M1!!g2-_B$>3mG_1(Jt%=xQ4 zBQ?bWITZ?=YIp9>uOC2m))=_oJvFFlUQ#k0mhvljz4xu2r$(r6(VXu*tgqPPsowN= zB^);|p#VkqWikQwN%2{{Qe%jX z5>Q%qA;^gEpMX&j?gR*W)yJ~4|goW`ku`7=vi*7GxoWJaK|#%VmgDoAhV;+!fXs;_?H w=*2pf!PZ#{Jisg3 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 Q_VenY`a<1`U(d1yPvoBf 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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%0DxzCd1))lz|vC0a-ssClI&G!JiKqh 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∨y)in%^nq1oy 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%0Aj!R?O@$N;%+*NW>$G8i(; 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 mF-= t { + break + } + } + commit, err := share.RecoverCommit(suite.G1(), pubShares, t, n) + if err != nil { + return nil, err + } + sig, err := commit.MarshalBinary() + if err != nil { + return nil, err + } + return sig, nil +} diff --git a/kyber/sign/tbls/tbls_test.go b/kyber/sign/tbls/tbls_test.go new file mode 100644 index 0000000000..5254bb7f6a --- /dev/null +++ b/kyber/sign/tbls/tbls_test.go @@ -0,0 +1,31 @@ +package tbls + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3/pairing/bn256" + "go.dedis.ch/kyber/v3/share" + "go.dedis.ch/kyber/v3/sign/bls" +) + +func TestTBLS(test *testing.T) { + var err error + msg := []byte("Hello threshold Boneh-Lynn-Shacham") + suite := bn256.NewSuite() + n := 10 + t := n/2 + 1 + secret := suite.G1().Scalar().Pick(suite.RandomStream()) + priPoly := share.NewPriPoly(suite.G2(), t, secret, suite.RandomStream()) + pubPoly := priPoly.Commit(suite.G2().Point().Base()) + sigShares := make([][]byte, 0) + for _, x := range priPoly.Shares(n) { + sig, err := Sign(suite, x, msg) + require.Nil(test, err) + sigShares = append(sigShares, sig) + } + sig, err := Recover(suite, pubPoly, msg, sigShares, t, n) + require.Nil(test, err) + err = bls.Verify(suite, pubPoly.Commit(), msg, sig) + require.Nil(test, err) +} diff --git a/kyber/suites/all.go b/kyber/suites/all.go new file mode 100644 index 0000000000..616235d3ed --- /dev/null +++ b/kyber/suites/all.go @@ -0,0 +1,22 @@ +package suites + +import ( + "go.dedis.ch/kyber/v3/group/edwards25519" + "go.dedis.ch/kyber/v3/group/nist" + "go.dedis.ch/kyber/v3/pairing" + "go.dedis.ch/kyber/v3/pairing/bn256" +) + +func init() { + // Those are variable time suites that shouldn't be used + // in production environment when possible + register(nist.NewBlakeSHA256P256()) + register(nist.NewBlakeSHA256QR512()) + register(bn256.NewSuiteG1()) + register(bn256.NewSuiteG2()) + register(bn256.NewSuiteGT()) + register(pairing.NewSuiteBn256()) + // This is a constant time implementation that should be + // used as much as possible + register(edwards25519.NewBlakeSHA256Ed25519()) +} diff --git a/kyber/suites/suites.go b/kyber/suites/suites.go new file mode 100644 index 0000000000..ab95395c46 --- /dev/null +++ b/kyber/suites/suites.go @@ -0,0 +1,67 @@ +// Package suites allows callers to look up Kyber suites by name. +// +// Currently, only the "ed25519" suite is available with a constant +// time implementation and the other ones use variable time algorithms. +package suites + +import ( + "errors" + "strings" + + "go.dedis.ch/kyber/v3" +) + +// Suite is the sum of all suites mix-ins in Kyber. +type Suite interface { + kyber.Encoding + kyber.Group + kyber.HashFactory + kyber.XOFFactory + kyber.Random +} + +var suites = map[string]Suite{} + +var requireConstTime = false + +// register is called by suites to make themselves known to Kyber. +// +func register(s Suite) { + suites[strings.ToLower(s.String())] = s +} + +// ErrUnknownSuite indicates that the suite was not one of the +// registered suites. +var ErrUnknownSuite = errors.New("unknown suite") + +// Find looks up a suite by name. +func Find(name string) (Suite, error) { + if s, ok := suites[strings.ToLower(name)]; ok { + if requireConstTime && strings.ToLower(s.String()) != "ed25519" { + return nil, errors.New("requested suite exists but is not implemented with constant time algorithms as required by suites.RequireConstantTime") + } + return s, nil + } + return nil, ErrUnknownSuite +} + +// MustFind looks up a suite by name and panics if it is not found. +func MustFind(name string) Suite { + s, err := Find(name) + if err != nil { + panic("Suite " + name + " not found.") + } + return s +} + +// RequireConstantTime causes all future calls to Find and MustFind to only +// search for suites where the implementation is constant time. +// It should be called in an init() function for the main package +// of users of Kyber who need to be sure to avoid variable time implementations. +// Once constant time implementations are required, there is no way to +// turn it back off (by design). +// +// At this time, the only constant time crypto suite is "Ed25519". +func RequireConstantTime() { + requireConstTime = true +} diff --git a/kyber/suites/suites_test.go b/kyber/suites/suites_test.go new file mode 100644 index 0000000000..3027a92f22 --- /dev/null +++ b/kyber/suites/suites_test.go @@ -0,0 +1,40 @@ +package suites + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestSuites_Find(t *testing.T) { + ss := []string{ + "ed25519", + "bn256.G1", + "bn256.G2", + "bn256.GT", + "P256", + "Residue512", + } + + for _, name := range ss { + s, err := Find(name) + require.NotNil(t, s, "missing "+name) + require.NoError(t, err) + + s = MustFind(name) + require.NotNil(t, s, "missing "+name) + } +} + +func TestSuites_ConstTime(t *testing.T) { + RequireConstantTime() + defer func() { requireConstTime = false }() + + s, err := Find("bn256.G1") + require.Error(t, err) + require.Nil(t, s) + + s, err = Find("ed25519") + require.NoError(t, err) + require.NotNil(t, s) +} diff --git a/kyber/util/encoding/encoding.go b/kyber/util/encoding/encoding.go new file mode 100644 index 0000000000..f1f86b6d15 --- /dev/null +++ b/kyber/util/encoding/encoding.go @@ -0,0 +1,96 @@ +// Package encoding package provides helper functions to encode/decode a Point/Scalar in +// hexadecimal. +package encoding + +import ( + "encoding/hex" + "errors" + "io" + "strings" + + "go.dedis.ch/kyber/v3" +) + +// ReadHexPoint reads a point from r in hex representation. +func ReadHexPoint(group kyber.Group, r io.Reader) (kyber.Point, error) { + point := group.Point() + buf, err := getHex(r, point.MarshalSize()) + if err != nil { + return nil, err + } + err = point.UnmarshalBinary(buf) + return point, err +} + +// WriteHexPoint writes a point in hex representation to w. +func WriteHexPoint(group kyber.Group, w io.Writer, point kyber.Point) error { + buf, err := point.MarshalBinary() + if err != nil { + return err + } + out := hex.EncodeToString(buf) + _, err = w.Write([]byte(out)) + return err +} + +// ReadHexScalar takes a hex-encoded scalar and returns that scalar, +// optionally an error +func ReadHexScalar(group kyber.Group, r io.Reader) (kyber.Scalar, error) { + s := group.Scalar() + buf, err := getHex(r, s.MarshalSize()) + if err != nil { + return nil, err + } + s.UnmarshalBinary(buf) + return s, nil +} + +// WriteHexScalar converts a scalar key to a hex-string +func WriteHexScalar(group kyber.Group, w io.Writer, scalar kyber.Scalar) error { + buf, err := scalar.MarshalBinary() + if err != nil { + return err + } + out := hex.EncodeToString(buf) + _, err = w.Write([]byte(out)) + return err +} + +// PointToStringHex converts a point to a hexadecimal representation +func PointToStringHex(group kyber.Group, point kyber.Point) (string, error) { + pbuf, err := point.MarshalBinary() + return hex.EncodeToString(pbuf), err +} + +// StringHexToPoint reads a hexadecimal representation of a point from a string. +func StringHexToPoint(group kyber.Group, s string) (kyber.Point, error) { + return ReadHexPoint(group, strings.NewReader(s)) +} + +// ScalarToStringHex encodes a scalar to hexadecimal. +func ScalarToStringHex(group kyber.Group, scalar kyber.Scalar) (string, error) { + sbuf, err := scalar.MarshalBinary() + return hex.EncodeToString(sbuf), err +} + +// StringHexToScalar reads a scalar in hexadecimal from string +func StringHexToScalar(group kyber.Group, str string) (kyber.Scalar, error) { + return ReadHexScalar(group, strings.NewReader(str)) +} + +func getHex(r io.Reader, l int) ([]byte, error) { + bufHex := make([]byte, l*2) + bufByte := make([]byte, l) + n, err := r.Read(bufHex) + if err != nil { + return nil, err + } + if n < len(bufHex) { + return nil, errors.New("didn't get enough bytes from stream") + } + _, err = hex.Decode(bufByte, bufHex) + if err != nil { + return nil, err + } + return bufByte, nil +} diff --git a/kyber/util/encoding/encoding_test.go b/kyber/util/encoding/encoding_test.go new file mode 100644 index 0000000000..f1a0cccdc6 --- /dev/null +++ b/kyber/util/encoding/encoding_test.go @@ -0,0 +1,62 @@ +package encoding + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3/group/edwards25519" +) + +var s = edwards25519.NewBlakeSHA256Ed25519() + +func ErrFatal(err error) { + if err == nil { + return + } + panic(err) +} + +func TestPubHexStream(t *testing.T) { + b := &bytes.Buffer{} + p := s.Point().Pick(s.RandomStream()) + ErrFatal(WriteHexPoint(s, b, p)) + ErrFatal(WriteHexPoint(s, b, p)) + p2, err := ReadHexPoint(s, b) + ErrFatal(err) + require.Equal(t, p.String(), p2.String()) + p2, err = ReadHexPoint(s, b) + ErrFatal(err) + require.Equal(t, p.String(), p2.String()) +} + +func TestScalarHexStream(t *testing.T) { + b := &bytes.Buffer{} + sc := s.Scalar().Pick(s.RandomStream()) + ErrFatal(WriteHexScalar(s, b, sc)) + ErrFatal(WriteHexScalar(s, b, sc)) + s2, err := ReadHexScalar(s, b) + ErrFatal(err) + require.True(t, sc.Equal(s2)) + s2, err = ReadHexScalar(s, b) + ErrFatal(err) + require.True(t, sc.Equal(s2)) +} + +func TestPubHexString(t *testing.T) { + p := s.Point().Pick(s.RandomStream()) + pstr, err := PointToStringHex(s, p) + ErrFatal(err) + p2, err := StringHexToPoint(s, pstr) + ErrFatal(err) + require.Equal(t, p.String(), p2.String()) +} + +func TestScalarHexString(t *testing.T) { + sc := s.Scalar().Pick(s.RandomStream()) + scstr, err := ScalarToStringHex(s, sc) + ErrFatal(err) + s2, err := StringHexToScalar(s, scstr) + ErrFatal(err) + require.True(t, sc.Equal(s2)) +} diff --git a/kyber/util/key/key.go b/kyber/util/key/key.go new file mode 100644 index 0000000000..f77c2d20ee --- /dev/null +++ b/kyber/util/key/key.go @@ -0,0 +1,49 @@ +// Package key creates asymmetric key pairs. +package key + +import ( + "crypto/cipher" + + "go.dedis.ch/kyber/v3" +) + +// Generator is a type that needs to implement a special case in order +// to correctly choose a key. +type Generator interface { + NewKey(random cipher.Stream) kyber.Scalar +} + +// Suite represents the list of functionalities needed by this package. +type Suite interface { + kyber.Group + kyber.Random +} + +// Pair represents a public/private keypair together with the +// ciphersuite the key was generated from. +type Pair struct { + Public kyber.Point // Public key + Private kyber.Scalar // Private key +} + +// NewKeyPair directly creates a secret/public key pair +func NewKeyPair(suite Suite) *Pair { + kp := new(Pair) + kp.Gen(suite) + return kp +} + +// Gen creates a fresh public/private keypair with the given +// ciphersuite, using a given source of cryptographic randomness. If +// suite implements key.Generator, then suite.NewKey is called +// to generate the private key, otherwise the normal technique +// of choosing a random scalar from the group is used. +func (p *Pair) Gen(suite Suite) { + random := suite.RandomStream() + if g, ok := suite.(Generator); ok { + p.Private = g.NewKey(random) + } else { + p.Private = suite.Scalar().Pick(random) + } + p.Public = suite.Point().Mul(p.Private, nil) +} diff --git a/kyber/util/key/key_test.go b/kyber/util/key/key_test.go new file mode 100644 index 0000000000..406032d7b8 --- /dev/null +++ b/kyber/util/key/key_test.go @@ -0,0 +1,39 @@ +package key + +import ( + "crypto/cipher" + "testing" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/group/edwards25519" +) + +func TestNewKeyPair(t *testing.T) { + suite := edwards25519.NewBlakeSHA256Ed25519() + keypair := NewKeyPair(suite) + pub := suite.Point().Mul(keypair.Private, nil) + if !pub.Equal(keypair.Public) { + t.Fatal("Public and private keys don't match") + } + t.Log(pub) +} + +// A type to test interface Generator by intentionally creating a fixed private key. +type fixedPrivSuiteEd25519 edwards25519.SuiteEd25519 + +func (s *fixedPrivSuiteEd25519) NewKey(stream cipher.Stream) kyber.Scalar { + return s.Scalar().SetInt64(33) +} + +// This is never called anyway, so it doesn't matter what it returns. +func (s *fixedPrivSuiteEd25519) RandomStream() cipher.Stream { return nil } + +func TestNewKeyPairGen(t *testing.T) { + suite := &fixedPrivSuiteEd25519{} + key := NewKeyPair(suite) + + scalar33 := suite.Scalar().SetInt64(33) + if !key.Private.Equal(scalar33) { + t.Fatalf("expected fixed private key, got %v", key.Private) + } +} diff --git a/kyber/util/random/rand.go b/kyber/util/random/rand.go new file mode 100644 index 0000000000..0fcee6fedc --- /dev/null +++ b/kyber/util/random/rand.go @@ -0,0 +1,78 @@ +// Package random provides facilities for generating +// random or pseudorandom cryptographic objects. +package random + +import ( + "crypto/cipher" + "crypto/rand" + "math/big" +) + +// Bits chooses a uniform random BigInt with a given maximum BitLen. +// If 'exact' is true, choose a BigInt with _exactly_ that BitLen, not less +func Bits(bitlen uint, exact bool, rand cipher.Stream) []byte { + b := make([]byte, (bitlen+7)/8) + rand.XORKeyStream(b, b) + highbits := bitlen & 7 + if highbits != 0 { + b[0] &= ^(0xff << highbits) + } + if exact { + if highbits != 0 { + b[0] |= 1 << (highbits - 1) + } else { + b[0] |= 0x80 + } + } + return b +} + +// Int chooses a uniform random big.Int less than a given modulus +func Int(mod *big.Int, rand cipher.Stream) *big.Int { + bitlen := uint(mod.BitLen()) + i := new(big.Int) + for { + i.SetBytes(Bits(bitlen, false, rand)) + if i.Sign() > 0 && i.Cmp(mod) < 0 { + return i + } + } +} + +// Bytes fills a slice with random bytes from rand. +func Bytes(b []byte, rand cipher.Stream) { + rand.XORKeyStream(b, b) +} + +type randstream struct { +} + +func (r *randstream) XORKeyStream(dst, src []byte) { + // This function works only on local data, so it is + // safe against race conditions, as long as crypto/rand + // is as well. (It is.) + + l := len(dst) + if len(src) != l { + panic("XORKeyStream: mismatched buffer lengths") + } + + buf := make([]byte, l) + n, err := rand.Read(buf) + if err != nil { + panic(err) + } + if n < len(buf) { + panic("short read on infinite random stream!?") + } + + for i := 0; i < l; i++ { + dst[i] = src[i] ^ buf[i] + } +} + +// New returns a new cipher.Stream that gets random data from Go's crypto/rand package. +// The resulting cipher.Stream can be used in multiple threads. +func New() cipher.Stream { + return &randstream{} +} diff --git a/kyber/util/test/doc.go b/kyber/util/test/doc.go new file mode 100644 index 0000000000..efb143b533 --- /dev/null +++ b/kyber/util/test/doc.go @@ -0,0 +1,3 @@ +// Package test contains generic testing and benchmarking infrastructure +// for cryptographic groups and ciphersuites. +package test diff --git a/kyber/util/test/group.go b/kyber/util/test/group.go new file mode 100644 index 0000000000..1aa4cf6ba1 --- /dev/null +++ b/kyber/util/test/group.go @@ -0,0 +1,150 @@ +package test + +import ( + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/util/random" +) + +// GroupBench is a generic benchmark suite for kyber.groups. +type GroupBench struct { + g kyber.Group + + // Random secrets and points for testing + x, y kyber.Scalar + X, Y kyber.Point + xe []byte // encoded Scalar + Xe []byte // encoded Point +} + +// NewGroupBench returns a new GroupBench. +func NewGroupBench(g kyber.Group) *GroupBench { + var gb GroupBench + rng := random.New() + gb.g = g + gb.x = g.Scalar().Pick(rng) + gb.y = g.Scalar().Pick(rng) + gb.xe, _ = gb.x.MarshalBinary() + gb.X = g.Point().Pick(rng) + gb.Y = g.Point().Pick(rng) + gb.Xe, _ = gb.X.MarshalBinary() + return &gb +} + +// ScalarAdd benchmarks the addition operation for scalars +func (gb GroupBench) ScalarAdd(iters int) { + for i := 1; i < iters; i++ { + gb.x.Add(gb.x, gb.y) + } +} + +// ScalarSub benchmarks the substraction operation for scalars +func (gb GroupBench) ScalarSub(iters int) { + for i := 1; i < iters; i++ { + gb.x.Sub(gb.x, gb.y) + } +} + +// ScalarNeg benchmarks the negation operation for scalars +func (gb GroupBench) ScalarNeg(iters int) { + for i := 1; i < iters; i++ { + gb.x.Neg(gb.x) + } +} + +// ScalarMul benchmarks the multiplication operation for scalars +func (gb GroupBench) ScalarMul(iters int) { + for i := 1; i < iters; i++ { + gb.x.Mul(gb.x, gb.y) + } +} + +// ScalarDiv benchmarks the division operation for scalars +func (gb GroupBench) ScalarDiv(iters int) { + for i := 1; i < iters; i++ { + gb.x.Div(gb.x, gb.y) + } +} + +// ScalarInv benchmarks the inverse operation for scalars +func (gb GroupBench) ScalarInv(iters int) { + for i := 1; i < iters; i++ { + gb.x.Inv(gb.x) + } +} + +// ScalarPick benchmarks the Pick operation for scalars +func (gb GroupBench) ScalarPick(iters int) { + for i := 1; i < iters; i++ { + gb.x.Pick(random.New()) + } +} + +// ScalarEncode benchmarks the marshalling operation for scalars +func (gb GroupBench) ScalarEncode(iters int) { + for i := 1; i < iters; i++ { + _, _ = gb.x.MarshalBinary() + } +} + +// ScalarDecode benchmarks the unmarshalling operation for scalars +func (gb GroupBench) ScalarDecode(iters int) { + for i := 1; i < iters; i++ { + _ = gb.x.UnmarshalBinary(gb.xe) + } +} + +// PointAdd benchmarks the addition operation for points +func (gb GroupBench) PointAdd(iters int) { + for i := 1; i < iters; i++ { + gb.X.Add(gb.X, gb.Y) + } +} + +// PointSub benchmarks the substraction operation for points +func (gb GroupBench) PointSub(iters int) { + for i := 1; i < iters; i++ { + gb.X.Sub(gb.X, gb.Y) + } +} + +// PointNeg benchmarks the negation operation for points +func (gb GroupBench) PointNeg(iters int) { + for i := 1; i < iters; i++ { + gb.X.Neg(gb.X) + } +} + +// PointMul benchmarks the multiplication operation for points +func (gb GroupBench) PointMul(iters int) { + for i := 1; i < iters; i++ { + gb.X.Mul(gb.y, gb.X) + } +} + +// PointBaseMul benchmarks the base multiplication operation for points +func (gb GroupBench) PointBaseMul(iters int) { + for i := 1; i < iters; i++ { + gb.X.Mul(gb.y, nil) + } +} + +// PointPick benchmarks the pick-ing operation for points +func (gb GroupBench) PointPick(iters int) { + for i := 1; i < iters; i++ { + gb.X.Pick(random.New()) + } +} + +// PointEncode benchmarks the encoding operation for points +func (gb GroupBench) PointEncode(iters int) { + for i := 1; i < iters; i++ { + _, _ = gb.X.MarshalBinary() + } +} + +// PointDecode benchmarks the decoding operation for points +func (gb GroupBench) PointDecode(iters int) { + for i := 1; i < iters; i++ { + _ = gb.X.UnmarshalBinary(gb.Xe) + } +} diff --git a/kyber/util/test/test.go b/kyber/util/test/test.go new file mode 100644 index 0000000000..f63a436c49 --- /dev/null +++ b/kyber/util/test/test.go @@ -0,0 +1,433 @@ +package test + +import ( + "bytes" + "crypto/cipher" + "testing" + + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/util/key" + "go.dedis.ch/kyber/v3/util/random" +) + +// Suite represents the functionalities that this package can test +type suite interface { + kyber.Group + kyber.HashFactory + kyber.XOFFactory + kyber.Random +} + +type suiteStable struct { + suite + xof kyber.XOF +} + +func newSuiteStable(s suite) *suiteStable { + return &suiteStable{ + suite: s, + xof: s.XOF(nil), + } +} + +func (ss *suiteStable) RandomStream() cipher.Stream { + return ss.xof +} + +func testEmbed(t *testing.T, g kyber.Group, rand cipher.Stream, points *[]kyber.Point, + s string) { + // println("embedding: ", s) + b := []byte(s) + + p := g.Point().Embed(b, rand) + x, err := p.Data() + if err != nil { + t.Errorf("Point extraction failed for %v: %v", p, err) + } + //println("extracted data (", len(x), " bytes): ", string(x)) + //println("EmbedLen(): ", g.Point().EmbedLen()) + max := g.Point().EmbedLen() + if max > len(b) { + max = len(b) + } + if !bytes.Equal(append(x, b[max:]...), b) { + t.Errorf("Point embedding corrupted the data") + } + + *points = append(*points, p) +} + +func testPointSet(t *testing.T, g kyber.Group, rand cipher.Stream) { + N := 1000 + null := g.Point().Null() + for i := 0; i < N; i++ { + P1 := g.Point().Pick(rand) + P2 := g.Point() + P2.Set(P1) + if !P1.Equal(P2) { + t.Errorf("Set() set to a different point: %v != %v", P1, P2) + } + if !P1.Equal(null) { + P1.Add(P1, P1) + if P1.Equal(P2) { + t.Errorf("Modifying P1 shouldn't modify P2: %v == %v", P1, P2) + } + } + } +} + +func testPointClone(t *testing.T, g kyber.Group, rand cipher.Stream) { + N := 1000 + null := g.Point().Null() + for i := 0; i < N; i++ { + P1 := g.Point().Pick(rand) + P2 := P1.Clone() + if !P1.Equal(P2) { + t.Errorf("Clone didn't work for point: %v != %v", P1, P2) + } + if !P1.Equal(null) { + P1.Add(P1, P1) + if P1.Equal(P2) { + t.Errorf("Modifying P1 shouldn't modify P2: %v == %v", P1, P2) + } + } + } +} + +func testScalarSet(t *testing.T, g kyber.Group, rand cipher.Stream) { + N := 1000 + zero := g.Scalar().Zero() + one := g.Scalar().One() + for i := 0; i < N; i++ { + s1 := g.Scalar().Pick(rand) + s2 := g.Scalar().Set(s1) + if !s1.Equal(s2) { + t.Errorf("Set() set to a different scalar: %v != %v", s1, s2) + } + if !s1.Equal(zero) && !s1.Equal(one) { + s1.Mul(s1, s1) + if s1.Equal(s2) { + t.Errorf("Modifying s1 shouldn't modify s2: %v == %v", s1, s2) + } + } + } +} + +func testScalarClone(t *testing.T, g kyber.Group, rand cipher.Stream) { + N := 1000 + zero := g.Scalar().Zero() + one := g.Scalar().One() + for i := 0; i < N; i++ { + s1 := g.Scalar().Pick(rand) + s2 := s1.Clone() + if !s1.Equal(s2) { + t.Errorf("Clone didn't work for scalar: %v != %v", s1, s2) + } + if !s1.Equal(zero) && !s1.Equal(one) { + s1.Mul(s1, s1) + if s1.Equal(s2) { + t.Errorf("Modifying s1 shouldn't modify s2: %v == %v", s1, s2) + } + } + } +} + +// Apply a generic set of validation tests to a cryptographic Group, +// using a given source of [pseudo-]randomness. +// +// Returns a log of the pseudorandom Points produced in the test, +// for comparison across alternative implementations +// that are supposed to be equivalent. +// +func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { + t.Logf("\nTesting group '%s': %d-byte Point, %d-byte Scalar\n", + g.String(), g.PointLen(), g.ScalarLen()) + + points := make([]kyber.Point, 0) + ptmp := g.Point() + stmp := g.Scalar() + pzero := g.Point().Null() + szero := g.Scalar().Zero() + sone := g.Scalar().One() + + // Do a simple Diffie-Hellman test + s1 := g.Scalar().Pick(rand) + s2 := g.Scalar().Pick(rand) + if s1.Equal(szero) { + t.Errorf("first secret is scalar zero %v", s1) + } + if s2.Equal(szero) { + t.Errorf("second secret is scalar zero %v", s2) + } + if s1.Equal(s2) { + t.Errorf("not getting unique secrets: picked %s twice", s1) + } + + gen := g.Point().Base() + points = append(points, gen) + + // Sanity-check relationship between addition and multiplication + p1 := g.Point().Add(gen, gen) + p2 := g.Point().Mul(stmp.SetInt64(2), nil) + if !p1.Equal(p2) { + t.Errorf("multiply by two doesn't work: %v == %v (+) %[2]v != %[2]v (x) 2 == %v", p1, gen, p2) + } + p1.Add(p1, p1) + p2.Mul(stmp.SetInt64(4), nil) + if !p1.Equal(p2) { + t.Errorf("multiply by four doesn't work: %v (+) %[1]v != %v (x) 4 == %v", + g.Point().Add(gen, gen), gen, p2) + } + points = append(points, p1) + + // Find out if this curve has a prime order: + // if the curve does not offer a method IsPrimeOrder, + // then assume that it is. + type canCheckPrimeOrder interface { + IsPrimeOrder() bool + } + primeOrder := true + if gpo, ok := g.(canCheckPrimeOrder); ok { + primeOrder = gpo.IsPrimeOrder() + } + + // Verify additive and multiplicative identities of the generator. + ptmp.Mul(stmp.SetInt64(-1), nil).Add(ptmp, gen) + if !ptmp.Equal(pzero) { + t.Errorf("generator additive identity doesn't work: %v (x) -1 (+) %v != %v the group point identity", + ptmp.Mul(stmp.SetInt64(-1), nil), gen, pzero) + } + // secret.Inv works only in prime-order groups + if primeOrder { + ptmp.Mul(stmp.SetInt64(2), nil).Mul(stmp.Inv(stmp), ptmp) + if !ptmp.Equal(gen) { + t.Errorf("generator multiplicative identity doesn't work:\n%v (x) %v = %v\n%[3]v (x) %v = %v", + ptmp.Base().String(), stmp.SetInt64(2).String(), + ptmp.Mul(stmp.SetInt64(2), nil).String(), + stmp.Inv(stmp).String(), + ptmp.Mul(stmp.SetInt64(2), nil).Mul(stmp.Inv(stmp), ptmp).String()) + } + } + + p1.Mul(s1, gen) + p2.Mul(s2, gen) + if p1.Equal(p2) { + t.Errorf("encryption isn't producing unique points: %v (x) %v == %v (x) %[2]v == %[4]v", s1, gen, s2, p1) + } + points = append(points, p1) + + dh1 := g.Point().Mul(s2, p1) + dh2 := g.Point().Mul(s1, p2) + if !dh1.Equal(dh2) { + t.Errorf("Diffie-Hellman didn't work: %v == %v (x) %v != %v (x) %v == %v", dh1, s2, p1, s1, p2, dh2) + } + points = append(points, dh1) + t.Logf("shared secret = %v", dh1) + + // Test secret inverse to get from dh1 back to p1 + if primeOrder { + ptmp.Mul(g.Scalar().Inv(s2), dh1) + if !ptmp.Equal(p1) { + t.Errorf("Scalar inverse didn't work: %v != (-)%v (x) %v == %v", p1, s2, dh1, ptmp) + } + } + + // Zero and One identity secrets + //println("dh1^0 = ",ptmp.Mul(dh1, szero).String()) + if !ptmp.Mul(szero, dh1).Equal(pzero) { + t.Errorf("Encryption with secret=0 didn't work: %v (x) %v == %v != %v", szero, dh1, ptmp, pzero) + } + if !ptmp.Mul(sone, dh1).Equal(dh1) { + t.Errorf("Encryption with secret=1 didn't work: %v (x) %v == %v != %[2]v", sone, dh1, ptmp) + } + + // Additive homomorphic identities + ptmp.Add(p1, p2) + stmp.Add(s1, s2) + pt2 := g.Point().Mul(stmp, gen) + if !pt2.Equal(ptmp) { + t.Errorf("Additive homomorphism doesn't work: %v + %v == %v, %[3]v (x) %v == %v != %v == %v (+) %v", + s1, s2, stmp, gen, pt2, ptmp, p1, p2) + } + ptmp.Sub(p1, p2) + stmp.Sub(s1, s2) + pt2.Mul(stmp, gen) + if !pt2.Equal(ptmp) { + t.Errorf("Additive homomorphism doesn't work: %v - %v == %v, %[3]v (x) %v == %v != %v == %v (-) %v", + s1, s2, stmp, gen, pt2, ptmp, p1, p2) + } + st2 := g.Scalar().Neg(s2) + st2.Add(s1, st2) + if !stmp.Equal(st2) { + t.Errorf("Scalar.Neg doesn't work: -%v == %v, %[2]v + %v == %v != %v", + s2, g.Scalar().Neg(s2), s1, st2, stmp) + } + pt2.Neg(p2).Add(pt2, p1) + if !pt2.Equal(ptmp) { + t.Errorf("Point.Neg doesn't work: (-)%v == %v, %[2]v (+) %v == %v != %v", + p2, g.Point().Neg(p2), p1, pt2, ptmp) + } + + // Multiplicative homomorphic identities + stmp.Mul(s1, s2) + if !ptmp.Mul(stmp, gen).Equal(dh1) { + t.Errorf("Multiplicative homomorphism doesn't work: %v * %v == %v, %[2]v (x) %v == %v != %v", + s1, s2, stmp, gen, ptmp, dh1) + } + if primeOrder { + st2.Inv(s2) + st2.Mul(st2, stmp) + if !st2.Equal(s1) { + t.Errorf("Scalar division doesn't work: %v^-1 * %v == %v * %[2]v == %[4]v != %v", + s2, stmp, g.Scalar().Inv(s2), st2, s1) + } + st2.Div(stmp, s2) + if !st2.Equal(s1) { + t.Errorf("Scalar division doesn't work: %v / %v == %v != %v", + stmp, s2, st2, s1) + } + } + + // Test randomly picked points + last := gen + for i := 0; i < 5; i++ { + rgen := g.Point().Pick(rand) + if rgen.Equal(last) { + t.Errorf("Pick() not producing unique points: got %v twice", rgen) + } + last = rgen + + ptmp.Mul(stmp.SetInt64(-1), rgen).Add(ptmp, rgen) + if !ptmp.Equal(pzero) { + t.Errorf("random generator fails additive identity: %v (x) %v == %v, %v (+) %[3]v == %[5]v != %v", + g.Scalar().SetInt64(-1), rgen, g.Point().Mul(g.Scalar().SetInt64(-1), rgen), + rgen, g.Point().Mul(g.Scalar().SetInt64(-1), rgen), pzero) + } + if primeOrder { + ptmp.Mul(stmp.SetInt64(2), rgen).Mul(stmp.Inv(stmp), ptmp) + if !ptmp.Equal(rgen) { + t.Errorf("random generator fails multiplicative identity: %v (x) (2 (x) %v) == %v != %[2]v", + stmp, rgen, ptmp) + } + } + points = append(points, rgen) + } + + // Test embedding data + testEmbed(t, g, rand, &points, "Hi!") + testEmbed(t, g, rand, &points, "The quick brown fox jumps over the lazy dog") + + // Test verifiable secret sharing + + // Test encoding and decoding + buf := new(bytes.Buffer) + for i := 0; i < 5; i++ { + buf.Reset() + s := g.Scalar().Pick(rand) + if _, err := s.MarshalTo(buf); err != nil { + t.Errorf("encoding of secret fails: " + err.Error()) + } + if _, err := stmp.UnmarshalFrom(buf); err != nil { + t.Errorf("decoding of secret fails: " + err.Error()) + } + if !stmp.Equal(s) { + t.Errorf("decoding produces different secret than encoded") + } + + buf.Reset() + p := g.Point().Pick(rand) + if _, err := p.MarshalTo(buf); err != nil { + t.Errorf("encoding of point fails: " + err.Error()) + } + if _, err := ptmp.UnmarshalFrom(buf); err != nil { + t.Errorf("decoding of point fails: " + err.Error()) + } + if !ptmp.Equal(p) { + t.Errorf("decoding produces different point than encoded") + } + } + + // Test that we can marshal/ unmarshal null point + pzero = g.Point().Null() + b, _ := pzero.MarshalBinary() + repzero := g.Point() + err := repzero.UnmarshalBinary(b) + if err != nil { + t.Errorf("Could not unmarshall binary %v: %v", b, err) + } + + testPointSet(t, g, rand) + testPointClone(t, g, rand) + testScalarSet(t, g, rand) + testScalarClone(t, g, rand) + + return points +} + +// GroupTest applies a generic set of validation tests to a cryptographic Group. +func GroupTest(t *testing.T, g kyber.Group) { + testGroup(t, g, random.New()) +} + +// CompareGroups tests two group implementations that are supposed to be equivalent, +// and compare their results. +func CompareGroups(t *testing.T, fn func(key []byte) kyber.XOF, g1, g2 kyber.Group) { + + // Produce test results from the same pseudorandom seed + r1 := testGroup(t, g1, fn(nil)) + r2 := testGroup(t, g2, fn(nil)) + + // Compare resulting Points + for i := range r1 { + b1, _ := r1[i].MarshalBinary() + b2, _ := r2[i].MarshalBinary() + if !bytes.Equal(b1, b2) { + t.Errorf("unequal result-pair %v\n1: %v\n2: %v", + i, r1[i], r2[i]) + } + } +} + +// SuiteTest tests a standard set of validation tests to a ciphersuite. +func SuiteTest(t *testing.T, suite suite) { + + // Try hashing something + h := suite.Hash() + l := h.Size() + //println("HashLen: ", l) + + _, _ = h.Write([]byte("abc")) + hb := h.Sum(nil) + //println("Hash:") + //println(hex.Dump(hb)) + if h.Size() != l || len(hb) != l { + t.Errorf("inconsistent hash output length: %v vs %v vs %v", l, h.Size(), len(hb)) + } + + // Generate some pseudorandom bits + x := suite.XOF(hb) + sb := make([]byte, 128) + x.Read(sb) + //fmt.Println("Stream:") + //fmt.Println(hex.Dump(sb)) + + // Test if it generates two fresh keys + p1 := key.NewKeyPair(suite) + p2 := key.NewKeyPair(suite) + if p1.Private.Equal(p2.Private) { + t.Errorf("NewKeyPair returns the same secret key twice: %v", p1) + } + + // Test if it creates the same key with the same seed + p1 = new(key.Pair) + p2 = new(key.Pair) + + p1.Gen(newSuiteStable(suite)) + p2.Gen(newSuiteStable(suite)) + if !p1.Private.Equal(p2.Private) { + t.Errorf("NewKeyPair returns different keys for same seed: %v != %v", p1, p2) + } + + // Test the public-key group arithmetic + GroupTest(t, suite) +} diff --git a/kyber/xof.go b/kyber/xof.go new file mode 100644 index 0000000000..b1f4b735a8 --- /dev/null +++ b/kyber/xof.go @@ -0,0 +1,50 @@ +package kyber + +import ( + "crypto/cipher" + "io" +) + +// An XOF is an extendable output function, which is a cryptographic +// primitive that can take arbitrary input in the same way a hash +// function does, and then create a stream of output, up to a limit +// determined by the size of the internal state of the hash function +// the underlies the XOF. +// +// When XORKeyStream is called with zeros for the source, an XOF +// also acts as a PRNG. If it is seeded with an appropriate amount +// of keying material, it is a cryptographically secure source of random +// bits. +type XOF interface { + // Write absorbs more data into the hash's state. It panics if called + // after Read. Use Reseed() to reset the XOF into a state where more data + // can be absorbed via Write. + io.Writer + + // Read reads more output from the hash. It returns io.EOF if the + // limit of available data for reading has been reached. + io.Reader + + // An XOF implements cipher.Stream, so that callers can use XORKeyStream + // to encrypt/decrypt data. The key stream is read from the XOF using + // the io.Reader interface. If Read returns an error, then XORKeyStream + // will panic. + cipher.Stream + + // Reseed makes an XOF writeable again after it has been read from + // by sampling a key from it's output and initializing a fresh XOF implementation + // with that key. + Reseed() + + // Clone returns a copy of the XOF in its current state. + Clone() XOF +} + +// An XOFFactory is an interface that can be mixed in to local suite definitions. +type XOFFactory interface { + // XOF creates a new XOF, feeding seed to it via it's Write method. If seed + // is nil or []byte{}, the XOF is left unseeded, it will produce a fixed, predictable + // stream of bits (Caution: this behavior is useful for testing but fatal for + // production use). + XOF(seed []byte) XOF +} diff --git a/kyber/xof/blake2xb/blake.go b/kyber/xof/blake2xb/blake.go new file mode 100644 index 0000000000..9fdfeb049f --- /dev/null +++ b/kyber/xof/blake2xb/blake.go @@ -0,0 +1,85 @@ +// Package blake2xb provides an implementation of kyber.XOF based on the +// Blake2xb construction. +package blake2xb + +import ( + "go.dedis.ch/kyber/v3" + "golang.org/x/crypto/blake2b" +) + +type xof struct { + impl blake2b.XOF + // key is here to not make excess garbage during repeated calls + // to XORKeyStream. + key []byte +} + +// New creates a new XOF using the Blake2b hash. +func New(seed []byte) kyber.XOF { + seed1 := seed + var seed2 []byte + if len(seed) > blake2b.Size { + seed1 = seed[0:blake2b.Size] + seed2 = seed[blake2b.Size:] + } + b, err := blake2b.NewXOF(blake2b.OutputLengthUnknown, seed1) + if err != nil { + panic("blake2b.NewXOF should not return error: " + err.Error()) + } + + if seed2 != nil { + _, err := b.Write(seed2) + if err != nil { + panic("blake2b.XOF.Write should not return error: " + err.Error()) + } + } + return &xof{impl: b} +} + +func (x *xof) Clone() kyber.XOF { + return &xof{impl: x.impl.Clone()} +} + +func (x *xof) Read(dst []byte) (int, error) { + return x.impl.Read(dst) +} + +func (x *xof) Write(src []byte) (int, error) { + return x.impl.Write(src) +} + +func (x *xof) Reseed() { + // Use New to create a new one seeded with output from the old one. + if len(x.key) < 128 { + x.key = make([]byte, 128) + } else { + x.key = x.key[0:128] + } + x.Read(x.key) + y := New(x.key) + // Steal the XOF implementation, and put it inside of x. + x.impl = y.(*xof).impl +} + +func (x *xof) XORKeyStream(dst, src []byte) { + if len(dst) < len(src) { + panic("dst too short") + } + if len(x.key) < len(src) { + x.key = make([]byte, len(src)) + } else { + x.key = x.key[0:len(src)] + } + + n, err := x.Read(x.key) + if err != nil { + panic("blake xof error: " + err.Error()) + } + if n != len(src) { + panic("short read on key") + } + + for i := range src { + dst[i] = src[i] ^ x.key[i] + } +} diff --git a/kyber/xof/blake2xs/blake.go b/kyber/xof/blake2xs/blake.go new file mode 100644 index 0000000000..8a91862d31 --- /dev/null +++ b/kyber/xof/blake2xs/blake.go @@ -0,0 +1,85 @@ +// Package blake2xs provides an implementation of kyber.XOF based on the +// Blake2xs construction. +package blake2xs + +import ( + "go.dedis.ch/kyber/v3" + "golang.org/x/crypto/blake2s" +) + +type xof struct { + impl blake2s.XOF + // key is here to not make excess garbage during repeated calls + // to XORKeyStream. + key []byte +} + +// New creates a new XOF using the blake2s hash. +func New(seed []byte) kyber.XOF { + seed1 := seed + var seed2 []byte + if len(seed) > blake2s.Size { + seed1 = seed[0:blake2s.Size] + seed2 = seed[blake2s.Size:] + } + b, err := blake2s.NewXOF(blake2s.OutputLengthUnknown, seed1) + if err != nil { + panic("blake2s.NewXOF should not return error: " + err.Error()) + } + + if seed2 != nil { + _, err := b.Write(seed2) + if err != nil { + panic("blake2s.XOF.Write should not return error: " + err.Error()) + } + } + return &xof{impl: b} +} + +func (x *xof) Clone() kyber.XOF { + return &xof{impl: x.impl.Clone()} +} + +func (x *xof) Read(dst []byte) (int, error) { + return x.impl.Read(dst) +} + +func (x *xof) Write(src []byte) (int, error) { + return x.impl.Write(src) +} + +func (x *xof) Reseed() { + // Use New to create a new one seeded with output from the old one. + if len(x.key) < 128 { + x.key = make([]byte, 128) + } else { + x.key = x.key[0:128] + } + x.Read(x.key) + y := New(x.key) + // Steal the XOF implementation, and put it inside of x. + x.impl = y.(*xof).impl +} + +func (x *xof) XORKeyStream(dst, src []byte) { + if len(dst) < len(src) { + panic("dst too short") + } + if len(x.key) < len(src) { + x.key = make([]byte, len(src)) + } else { + x.key = x.key[0:len(src)] + } + + n, err := x.Read(x.key) + if err != nil { + panic("blake xof error: " + err.Error()) + } + if n != len(src) { + panic("short read on key") + } + + for i := range src { + dst[i] = src[i] ^ x.key[i] + } +} diff --git a/kyber/xof/doc.go b/kyber/xof/doc.go new file mode 100644 index 0000000000..3b415daa05 --- /dev/null +++ b/kyber/xof/doc.go @@ -0,0 +1,3 @@ +// Package xof holds implementations and testing code for the various +// extendable output functions. +package xof diff --git a/kyber/xof/keccak/keccak.go b/kyber/xof/keccak/keccak.go new file mode 100644 index 0000000000..d29e48c024 --- /dev/null +++ b/kyber/xof/keccak/keccak.go @@ -0,0 +1,68 @@ +// Package keccak provides an implementation of kyber.XOF based on the +// Shake256 hash. +package keccak + +import ( + "go.dedis.ch/kyber/v3" + "golang.org/x/crypto/sha3" +) + +type xof struct { + sh sha3.ShakeHash + // key is here to not make excess garbage during repeated calls + // to XORKeyStream. + key []byte +} + +// New creates a new XOF using the Shake256 hash. +func New(seed []byte) kyber.XOF { + sh := sha3.NewShake256() + sh.Write(seed) + return &xof{sh: sh} +} + +func (x *xof) Clone() kyber.XOF { + return &xof{sh: x.sh.Clone()} +} + +func (x *xof) Reseed() { + if len(x.key) < 128 { + x.key = make([]byte, 128) + } else { + x.key = x.key[0:128] + } + x.Read(x.key) + x.sh = sha3.NewShake256() + x.sh.Write(x.key) +} + +func (x *xof) Read(dst []byte) (int, error) { + return x.sh.Read(dst) +} + +func (x *xof) Write(src []byte) (int, error) { + return x.sh.Write(src) +} + +func (x *xof) XORKeyStream(dst, src []byte) { + if len(dst) < len(src) { + panic("dst too short") + } + if len(x.key) < len(src) { + x.key = make([]byte, len(src)) + } else { + x.key = x.key[0:len(src)] + } + + n, err := x.Read(x.key) + if err != nil { + panic("xof error getting key: " + err.Error()) + } + if n != len(src) { + panic("short read on key") + } + + for i := range src { + dst[i] = src[i] ^ x.key[i] + } +} diff --git a/kyber/xof/xof_test.go b/kyber/xof/xof_test.go new file mode 100644 index 0000000000..e1e844ee1f --- /dev/null +++ b/kyber/xof/xof_test.go @@ -0,0 +1,239 @@ +package xof + +import ( + "bytes" + "math" + "testing" + + "github.com/stretchr/testify/require" + "go.dedis.ch/kyber/v3" + "go.dedis.ch/kyber/v3/xof/blake2xb" + "go.dedis.ch/kyber/v3/xof/keccak" +) + +type blakeF struct{} + +func (b *blakeF) XOF(seed []byte) kyber.XOF { return blake2xb.New(seed) } + +type keccakF struct{} + +func (b *keccakF) XOF(seed []byte) kyber.XOF { return keccak.New(seed) } + +var impls = []kyber.XOFFactory{&blakeF{}, &keccakF{}} + +func TestEncDec(t *testing.T) { + lengths := []int{0, 1, 16, 1024, 8192} + + for _, i := range impls { + for _, j := range lengths { + testEncDec(t, i, j) + } + } +} + +func testEncDec(t *testing.T, s kyber.XOFFactory, size int) { + t.Logf("implementation %T sz %v", s, size) + key := []byte("key") + + s1 := s.XOF(key) + s2 := s.XOF(key) + + src := make([]byte, size) + copy(src, []byte("hello")) + + dst := make([]byte, len(src)+1) + dst[len(dst)-1] = 0xff + + s1.XORKeyStream(dst, src) + if len(src) > 0 && bytes.Equal(src, dst[0:len(src)]) { + t.Fatal("src/dst should not be equal") + } + if dst[len(dst)-1] != 0xff { + t.Fatal("last byte of dst chagned") + } + + dst2 := make([]byte, len(src)) + s2.XORKeyStream(dst2, dst[0:len(src)]) + if !bytes.Equal(src, dst2) { + t.Fatal("src/dst2 should be equal", src, dst2) + } +} + +func TestClone(t *testing.T) { + for _, i := range impls { + testClone(t, i) + } +} + +func testClone(t *testing.T, s kyber.XOFFactory) { + t.Logf("implementation %T", s) + key := []byte("key") + + s1 := s.XOF(key) + s2 := s1.Clone() + + src := []byte("hello") + dst := make([]byte, len(src)+1) + dst[len(dst)-1] = 0xff + + s1.XORKeyStream(dst, src) + if bytes.Equal(src, dst[0:len(src)]) { + t.Fatal("src/dst should not be equal") + } + if dst[len(dst)-1] != 0xff { + t.Fatal("last byte of dst chagned") + } + + dst2 := make([]byte, len(src)) + s2.XORKeyStream(dst2, dst[0:len(src)]) + if !bytes.Equal(src, dst2) { + t.Fatal("src/dst2 should be equal", src, dst2) + } +} + +func TestErrors(t *testing.T) { + for _, i := range impls { + testErrors(t, i) + } +} + +func testErrors(t *testing.T, s kyber.XOFFactory) { + t.Logf("implementation %T", s) + + // Write-after-read: panic + key := []byte("key") + s1 := s.XOF(key) + src := []byte("hello") + dst := make([]byte, 100) + s1.XORKeyStream(dst, src) + require.Panics(t, func() { s1.Write(src) }) + + // Dst too short: panic + require.Panics(t, func() { s1.XORKeyStream(dst[0:len(src)-1], src) }) +} + +func TestRandom(t *testing.T) { + for _, i := range impls { + testRandom(t, i) + } +} + +func testRandom(t *testing.T, s kyber.XOFFactory) { + t.Logf("implementation %T", s) + xof1 := s.XOF(nil) + + for i := 0; i < 1000; i++ { + dst1 := make([]byte, 1024) + xof1.Read(dst1) + dst2 := make([]byte, 1024) + xof1.Read(dst2) + d := bitDiff(dst1, dst2) + if math.Abs(d-0.50) > 0.1 { + t.Fatalf("bitDiff %v", d) + } + } + + // Check that two seeds give expected mean bitdiff on first block + xof1 = s.XOF([]byte("a")) + xof2 := s.XOF([]byte("b")) + dst1 := make([]byte, 1024) + xof1.Read(dst1) + dst2 := make([]byte, 1024) + xof2.Read(dst2) + d := bitDiff(dst1, dst2) + if math.Abs(d-0.50) > 0.1 { + t.Fatalf("two seed bitDiff %v", d) + } +} + +// bitDiff compares the bits between two arrays returning the fraction +// of differences. If the two arrays are not of the same length +// no comparison is made and a -1 is returned. +func bitDiff(a, b []byte) float64 { + if len(a) != len(b) { + return -1 + } + + count := 0 + for i := 0; i < len(a); i++ { + for j := 0; j < 8; j++ { + count += int(((a[i] ^ b[i]) >> uint(j)) & 1) + } + } + + return float64(count) / float64(len(a)*8) +} + +func TestNoSeed(t *testing.T) { + for _, i := range impls { + testNoSeed(t, i) + } +} + +func testNoSeed(t *testing.T, s kyber.XOFFactory) { + t.Logf("implementation %T", s) + + xof1 := s.XOF(nil) + dst1 := make([]byte, 1024) + xof1.Read(dst1) + + xof2 := s.XOF([]byte{}) + dst2 := make([]byte, 1024) + xof2.Read(dst2) + if !bytes.Equal(dst1, dst2) { + t.Fatal("hash with two flavors of zero seed not same") + } +} + +func TestReseed(t *testing.T) { + for _, i := range impls { + testReseed(t, i) + } +} + +func testReseed(t *testing.T, s kyber.XOFFactory) { + t.Logf("implementation %T", s) + seed := []byte("seed") + + xof1 := s.XOF(seed) + dst1 := make([]byte, 1024) + xof1.Read(dst1) + // Without Reseed: panic. + require.Panics(t, func() { xof1.Write(seed) }) + // After Reseed, does not panic. + xof1.Reseed() + xof2 := xof1.Clone() + require.NotPanics(t, func() { xof1.Write(seed) }) + + dst2 := make([]byte, 1024) + xof2.Read(dst2) + + d := bitDiff(dst1, dst2) + if math.Abs(d-0.50) > 0.1 { + t.Fatalf("reseed bitDiff %v", d) + } +} + +func TestEncDecMismatch(t *testing.T) { + for _, i := range impls { + testEncDecMismatch(t, i) + } +} + +func testEncDecMismatch(t *testing.T, s kyber.XOFFactory) { + t.Logf("implementation %T", s) + seed := []byte("seed") + x1 := s.XOF(seed) + x2 := s.XOF(seed) + msg := []byte("hello world") + enc := make([]byte, len(msg)) + dec := make([]byte, len(msg)) + x1.XORKeyStream(enc[0:3], msg[0:3]) + x1.XORKeyStream(enc[3:4], msg[3:4]) + x1.XORKeyStream(enc[4:], msg[4:]) + x2.XORKeyStream(dec[0:5], enc[0:5]) + x2.XORKeyStream(dec[5:], enc[5:]) + if !bytes.Equal(msg, dec) { + t.Fatal("wrong decode") + } +} diff --git a/ocs/demo/.gitignore b/ocs/demo/.gitignore new file mode 100644 index 0000000000..ac6b375235 --- /dev/null +++ b/ocs/demo/.gitignore @@ -0,0 +1,3 @@ +data/*db +data/log +data/running diff --git a/ocs/demo/data/co1/private.toml b/ocs/demo/data/co1/private.toml new file mode 100644 index 0000000000..43e7e3df2b --- /dev/null +++ b/ocs/demo/data/co1/private.toml @@ -0,0 +1,24 @@ +# This file contains your private key. +# Do not give it away lightly! +Suite = "Ed25519" +Public = "c4efdc8ac09e40f1a34345f7964ad020d446ffa0745cbafc0b30113cb7529825" +Private = "0d680d146821f37c6b33d8291e5c0e5b9adec969395625732eedb7999d40e40b" +Address = "tls://localhost:7770" +ListenAddress = "" +Description = "Conode_1" +WebSocketTLSCertificate = "" +WebSocketTLSCertificateKey = "" + +[Services] + [Services.ByzCoin] + Suite = "bn256.adapter" + Public = "6527fcb277c43ae042011b7db5bb86722fd6c89c9c9e18a31a2b5ed62b2ca7ae832e718d6b1c50172d836366097435d4522f2765c367bfe68e3db7450142c41c22a6a99bcee7257c96e04aae9e15353b1e1da1c2bce878652aa67cbd66baf4967401d04a79039a5c5e67f42ebceb6c97063bc72f48a64067b15a65a938f63a84" + Private = "668058a926e86b13afd96240027c01b50c4d60d629e6f5bbdf1b5eca55565c0a" + [Services.OCS] + Suite = "Ed25519" + Public = "8a43093fd9dc22249552e40b8e895112722785372a0fcd777bf09c66b5cbdc14" + Private = "1c758d426d63ce188112a2c821c97db8301b350d3a5bd7c0dac235509cb05007" + [Services.Skipchain] + Suite = "bn256.adapter" + Public = "053636059f263f4c6eea8c0175a2e4886f1f8999f7bff8bd5791976e1ea8e03d0e5567f71e95dc196387767e4373ca580ff43498ceccef582ecabfcca08b683175f9f0100283236dfba5e242f90b9e75db0c12f1dd5d3f1cc3eb110baab48e4204736ef14018b40da4218055859a0a8b9fbb732300a63c0df89a75123c0ec3e3" + Private = "47018e12482e42de967939855e5c66086e4ca55e69d7d9714d1f6cff38397bdb" diff --git a/ocs/demo/data/co1/public.toml b/ocs/demo/data/co1/public.toml new file mode 100644 index 0000000000..d3fa2e7970 --- /dev/null +++ b/ocs/demo/data/co1/public.toml @@ -0,0 +1,15 @@ +[[servers]] + Address = "tls://localhost:7770" + Suite = "Ed25519" + Public = "c4efdc8ac09e40f1a34345f7964ad020d446ffa0745cbafc0b30113cb7529825" + Description = "Conode_1" + [servers.Services] + [servers.Services.ByzCoin] + Public = "6527fcb277c43ae042011b7db5bb86722fd6c89c9c9e18a31a2b5ed62b2ca7ae832e718d6b1c50172d836366097435d4522f2765c367bfe68e3db7450142c41c22a6a99bcee7257c96e04aae9e15353b1e1da1c2bce878652aa67cbd66baf4967401d04a79039a5c5e67f42ebceb6c97063bc72f48a64067b15a65a938f63a84" + Suite = "bn256.adapter" + [servers.Services.OCS] + Public = "8a43093fd9dc22249552e40b8e895112722785372a0fcd777bf09c66b5cbdc14" + Suite = "Ed25519" + [servers.Services.Skipchain] + Public = "053636059f263f4c6eea8c0175a2e4886f1f8999f7bff8bd5791976e1ea8e03d0e5567f71e95dc196387767e4373ca580ff43498ceccef582ecabfcca08b683175f9f0100283236dfba5e242f90b9e75db0c12f1dd5d3f1cc3eb110baab48e4204736ef14018b40da4218055859a0a8b9fbb732300a63c0df89a75123c0ec3e3" + Suite = "bn256.adapter" diff --git a/ocs/demo/data/co2/private.toml b/ocs/demo/data/co2/private.toml new file mode 100644 index 0000000000..c1f39af652 --- /dev/null +++ b/ocs/demo/data/co2/private.toml @@ -0,0 +1,24 @@ +# This file contains your private key. +# Do not give it away lightly! +Suite = "Ed25519" +Public = "745e4b38435ee95063e00131aeeaaec5e7d020b96e91191c03bc2c8bfda1e99e" +Private = "f4f83a5ea70f95562d7fed51dad13f0bb3255e96d9d6dffe0b4c3b3492aff104" +Address = "tls://localhost:7772" +ListenAddress = "" +Description = "Conode_2" +WebSocketTLSCertificate = "" +WebSocketTLSCertificateKey = "" + +[Services] + [Services.ByzCoin] + Suite = "bn256.adapter" + Public = "5007870767e42c866e628ae10d81db110dc9d07f1d2a613ba5c3fb4c1f69039507ee38e26c50588452c5603cea0eaaadf8137b83bae8eb5a0ae5555a4e0808ec52c005e20e4eacc5d26547811a899046c0b0e72578199252ad8655561015e2f61e4f0751058d90aa8743a4b0781ecfe60ad55b234e55a2e3554146294ed0fd47" + Private = "3ac75a0f4bd1d769fc8dbf84010882a488c2a23edf8280f6541b645277c0e28d" + [Services.OCS] + Suite = "Ed25519" + Public = "007d538282a8e0ca6bfd7fa9690f744b08ff36edc5c7be960088ca94b4eec3cd" + Private = "0cdd2daddcc471b02865d47bcd67f9cedbfe4d04ec377ad55521d828e8a0180d" + [Services.Skipchain] + Suite = "bn256.adapter" + Public = "8bf59a9c5227c84346f9701488d5cbf469a3f600481e3233217699c8d42642c05369613a20e35988bac7d1743d35800014470c9b8e5ff04ed1f40d0aace81ee91e4ea1a1f2a6fd0b2f669da19e312d53229331a05c20f48f9e19eedc19c2a8345d7ecb52ed6b53bdf6c3d7058833ddb4202504462ef83665cdd72f20406f5d9c" + Private = "7cc33dea17f6606c27f34a6b14e1af123e6bb207f3d7f1aa0e68812b0a1c7ae8" diff --git a/ocs/demo/data/co2/public.toml b/ocs/demo/data/co2/public.toml new file mode 100644 index 0000000000..47d1fbe024 --- /dev/null +++ b/ocs/demo/data/co2/public.toml @@ -0,0 +1,15 @@ +[[servers]] + Address = "tls://localhost:7772" + Suite = "Ed25519" + Public = "745e4b38435ee95063e00131aeeaaec5e7d020b96e91191c03bc2c8bfda1e99e" + Description = "Conode_2" + [servers.Services] + [servers.Services.ByzCoin] + Public = "5007870767e42c866e628ae10d81db110dc9d07f1d2a613ba5c3fb4c1f69039507ee38e26c50588452c5603cea0eaaadf8137b83bae8eb5a0ae5555a4e0808ec52c005e20e4eacc5d26547811a899046c0b0e72578199252ad8655561015e2f61e4f0751058d90aa8743a4b0781ecfe60ad55b234e55a2e3554146294ed0fd47" + Suite = "bn256.adapter" + [servers.Services.OCS] + Public = "007d538282a8e0ca6bfd7fa9690f744b08ff36edc5c7be960088ca94b4eec3cd" + Suite = "Ed25519" + [servers.Services.Skipchain] + Public = "8bf59a9c5227c84346f9701488d5cbf469a3f600481e3233217699c8d42642c05369613a20e35988bac7d1743d35800014470c9b8e5ff04ed1f40d0aace81ee91e4ea1a1f2a6fd0b2f669da19e312d53229331a05c20f48f9e19eedc19c2a8345d7ecb52ed6b53bdf6c3d7058833ddb4202504462ef83665cdd72f20406f5d9c" + Suite = "bn256.adapter" diff --git a/ocs/demo/data/co3/private.toml b/ocs/demo/data/co3/private.toml new file mode 100644 index 0000000000..4e49b3acc3 --- /dev/null +++ b/ocs/demo/data/co3/private.toml @@ -0,0 +1,24 @@ +# This file contains your private key. +# Do not give it away lightly! +Suite = "Ed25519" +Public = "9e7e85c908ef170d68f2820945905cf9e8eeae563e4a7c15af8d889b021e4537" +Private = "8fd568f157ea1032ae018d7b8b1f39a6cd570ea9dc1b90bac6e2d991dcc65004" +Address = "tls://localhost:7774" +ListenAddress = "" +Description = "Conode_3" +WebSocketTLSCertificate = "" +WebSocketTLSCertificateKey = "" + +[Services] + [Services.ByzCoin] + Suite = "bn256.adapter" + Public = "4de98971d890a0ab48e7703a9c82edacabbee45e45e25670b10fc738a2c0eb9d85b729bf2fa0f1af753940ea2355f8aab2848b1a5f745820721606105a8b5acd8d8cf15d069a46a82d4349bd8322a5618569ce559a433f7ae570913a578e9b0e0cd8466668aa1fdaacb91cb74058c8afe135e2c541b2a8234f3a669c8a22bbe3" + Private = "5a6e55227ffb1d770c8a4a7b7525b682eab178bfa912be051aec2378a3f8366f" + [Services.OCS] + Suite = "Ed25519" + Public = "e8f63c82676019971398ff4738ee4b6e9e85f56eab9f83f8773718d8a555a685" + Private = "72b1f4f61cce1c92451ad3e2a13c244628d09bab0af2c1eab16eda921472a20a" + [Services.Skipchain] + Suite = "bn256.adapter" + Public = "5644cb44572f053e0dcd42ff1a4bca9f04eb8e987a7f065dd098507517193a533bb790fa59ff114f082509f9884b24e6d6761753b3c3f01de3c1af9609e150eb764433303d3b44dd6d3e56a75f67165c10965a08399faecd46a07c158779491a4f8e9e294e22a1fd68df2cd68cdc6866ff8cfcd1070b0c394f00062ecc7c4894" + Private = "2aa8d8bb5bb1245cea793cf1a0df7529cd0930ae565133fca9124ccf71f63071" diff --git a/ocs/demo/data/co3/public.toml b/ocs/demo/data/co3/public.toml new file mode 100644 index 0000000000..0dbd0feb44 --- /dev/null +++ b/ocs/demo/data/co3/public.toml @@ -0,0 +1,15 @@ +[[servers]] + Address = "tls://localhost:7774" + Suite = "Ed25519" + Public = "9e7e85c908ef170d68f2820945905cf9e8eeae563e4a7c15af8d889b021e4537" + Description = "Conode_3" + [servers.Services] + [servers.Services.ByzCoin] + Public = "4de98971d890a0ab48e7703a9c82edacabbee45e45e25670b10fc738a2c0eb9d85b729bf2fa0f1af753940ea2355f8aab2848b1a5f745820721606105a8b5acd8d8cf15d069a46a82d4349bd8322a5618569ce559a433f7ae570913a578e9b0e0cd8466668aa1fdaacb91cb74058c8afe135e2c541b2a8234f3a669c8a22bbe3" + Suite = "bn256.adapter" + [servers.Services.OCS] + Public = "e8f63c82676019971398ff4738ee4b6e9e85f56eab9f83f8773718d8a555a685" + Suite = "Ed25519" + [servers.Services.Skipchain] + Public = "5644cb44572f053e0dcd42ff1a4bca9f04eb8e987a7f065dd098507517193a533bb790fa59ff114f082509f9884b24e6d6761753b3c3f01de3c1af9609e150eb764433303d3b44dd6d3e56a75f67165c10965a08399faecd46a07c158779491a4f8e9e294e22a1fd68df2cd68cdc6866ff8cfcd1070b0c394f00062ecc7c4894" + Suite = "bn256.adapter" diff --git a/ocs/demo/data/public.toml b/ocs/demo/data/public.toml new file mode 100644 index 0000000000..b3e4531f5d --- /dev/null +++ b/ocs/demo/data/public.toml @@ -0,0 +1,45 @@ +[[servers]] + Address = "tls://localhost:7774" + Suite = "Ed25519" + Public = "9e7e85c908ef170d68f2820945905cf9e8eeae563e4a7c15af8d889b021e4537" + Description = "Conode_3" + [servers.Services] + [servers.Services.ByzCoin] + Public = "4de98971d890a0ab48e7703a9c82edacabbee45e45e25670b10fc738a2c0eb9d85b729bf2fa0f1af753940ea2355f8aab2848b1a5f745820721606105a8b5acd8d8cf15d069a46a82d4349bd8322a5618569ce559a433f7ae570913a578e9b0e0cd8466668aa1fdaacb91cb74058c8afe135e2c541b2a8234f3a669c8a22bbe3" + Suite = "bn256.adapter" + [servers.Services.OCS] + Public = "e8f63c82676019971398ff4738ee4b6e9e85f56eab9f83f8773718d8a555a685" + Suite = "Ed25519" + [servers.Services.Skipchain] + Public = "5644cb44572f053e0dcd42ff1a4bca9f04eb8e987a7f065dd098507517193a533bb790fa59ff114f082509f9884b24e6d6761753b3c3f01de3c1af9609e150eb764433303d3b44dd6d3e56a75f67165c10965a08399faecd46a07c158779491a4f8e9e294e22a1fd68df2cd68cdc6866ff8cfcd1070b0c394f00062ecc7c4894" + Suite = "bn256.adapter" +[[servers]] + Address = "tls://localhost:7772" + Suite = "Ed25519" + Public = "745e4b38435ee95063e00131aeeaaec5e7d020b96e91191c03bc2c8bfda1e99e" + Description = "Conode_2" + [servers.Services] + [servers.Services.ByzCoin] + Public = "5007870767e42c866e628ae10d81db110dc9d07f1d2a613ba5c3fb4c1f69039507ee38e26c50588452c5603cea0eaaadf8137b83bae8eb5a0ae5555a4e0808ec52c005e20e4eacc5d26547811a899046c0b0e72578199252ad8655561015e2f61e4f0751058d90aa8743a4b0781ecfe60ad55b234e55a2e3554146294ed0fd47" + Suite = "bn256.adapter" + [servers.Services.OCS] + Public = "007d538282a8e0ca6bfd7fa9690f744b08ff36edc5c7be960088ca94b4eec3cd" + Suite = "Ed25519" + [servers.Services.Skipchain] + Public = "8bf59a9c5227c84346f9701488d5cbf469a3f600481e3233217699c8d42642c05369613a20e35988bac7d1743d35800014470c9b8e5ff04ed1f40d0aace81ee91e4ea1a1f2a6fd0b2f669da19e312d53229331a05c20f48f9e19eedc19c2a8345d7ecb52ed6b53bdf6c3d7058833ddb4202504462ef83665cdd72f20406f5d9c" + Suite = "bn256.adapter" +[[servers]] + Address = "tls://localhost:7770" + Suite = "Ed25519" + Public = "c4efdc8ac09e40f1a34345f7964ad020d446ffa0745cbafc0b30113cb7529825" + Description = "Conode_1" + [servers.Services] + [servers.Services.ByzCoin] + Public = "6527fcb277c43ae042011b7db5bb86722fd6c89c9c9e18a31a2b5ed62b2ca7ae832e718d6b1c50172d836366097435d4522f2765c367bfe68e3db7450142c41c22a6a99bcee7257c96e04aae9e15353b1e1da1c2bce878652aa67cbd66baf4967401d04a79039a5c5e67f42ebceb6c97063bc72f48a64067b15a65a938f63a84" + Suite = "bn256.adapter" + [servers.Services.OCS] + Public = "8a43093fd9dc22249552e40b8e895112722785372a0fcd777bf09c66b5cbdc14" + Suite = "Ed25519" + [servers.Services.Skipchain] + Public = "053636059f263f4c6eea8c0175a2e4886f1f8999f7bff8bd5791976e1ea8e03d0e5567f71e95dc196387767e4373ca580ff43498ceccef582ecabfcca08b683175f9f0100283236dfba5e242f90b9e75db0c12f1dd5d3f1cc3eb110baab48e4204736ef14018b40da4218055859a0a8b9fbb732300a63c0df89a75123c0ec3e3" + Suite = "bn256.adapter" diff --git a/ocs/demo/main.go b/ocs/demo/main.go index ef4eb76ef0..f622764c60 100644 --- a/ocs/demo/main.go +++ b/ocs/demo/main.go @@ -13,7 +13,7 @@ import ( "os" "strings" - "go.dedis.ch/cothority/v3/ocs/edwards25519" + "go.dedis.ch/kyber/v3/group/edwards25519" "go.dedis.ch/kyber/v3" @@ -25,8 +25,6 @@ import ( ) func main() { - // Use our own ed25519 suite to be able to print x coordinates: - cothority.Suite = edwards25519.NewBlakeSHA256Ed25519() if len(os.Args) < 2 { log.Error("Please give a roster.toml as first parameter") printSamples()