Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Bugfixes supporting the CCS artifacts version #3

Merged
merged 47 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3475db4
bump to lattigo v5.0.2
ChristianMct Mar 18, 2024
e47c18c
prepared ckks support, bgv tests passing
ChristianMct Apr 3, 2024
e4450c5
added ckks support and tests at the service layer
ChristianMct Apr 5, 2024
1849df6
renamed session.Parameters.FHEParameter field & updated README
ChristianMct Apr 5, 2024
fce7111
depluralized package names: protocol and circuit
ChristianMct Apr 5, 2024
b2342ed
added passing late connect test and skipped retry test
ChristianMct Apr 9, 2024
ac93572
added executor retries and basic test for setup
ChristianMct Apr 10, 2024
1af71da
working setup-service init from Run
ChristianMct Apr 11, 2024
42f763c
added generic coordinator interface and localtest
ChristianMct Apr 14, 2024
3c2f52f
using generic coordinator in compute service
ChristianMct Apr 14, 2024
dc31b15
streamlined services transports and fixed buggy services init
ChristianMct Apr 15, 2024
ca97f58
adapted node package to unified coordinator/transport api
ChristianMct Apr 16, 2024
9c43fd9
working setup with grpc transport
ChristianMct Apr 16, 2024
2cfd6cf
working compute
ChristianMct Apr 17, 2024
bca5704
adapted example
ChristianMct Apr 17, 2024
268afce
moved id types in session package
ChristianMct Apr 17, 2024
2dc6b40
moved node-related type to node package
ChristianMct Apr 17, 2024
89635ac
moved urls to compute package and tls config to node package
ChristianMct Apr 17, 2024
2d7c77c
symbole cleaning in session package
ChristianMct Apr 17, 2024
47f2b6e
moved entrypoint types and funcs in the main helium package, moved pr…
ChristianMct Apr 17, 2024
e0bee6f
adding some godoc
ChristianMct Apr 17, 2024
6f30621
added service-based network stats
ChristianMct Apr 17, 2024
2dd53ab
cleaned up context keys
ChristianMct Apr 17, 2024
f36b68c
re-pluralized relevant packages and updated CHANGELOG
ChristianMct Apr 18, 2024
2f55adb
some debug info
ChristianMct Apr 18, 2024
a9cc516
artifact experiment support
ChristianMct Apr 19, 2024
582dd71
re-enabled timeouts
ChristianMct Apr 21, 2024
89bacac
attempt fix bad node event closing
ChristianMct Apr 21, 2024
32ee891
increase sendqueue size
ChristianMct Apr 22, 2024
d72e844
failing RKG1 reruns RKG
ChristianMct Apr 22, 2024
11533f7
handling of failing RKG
ChristianMct Apr 22, 2024
1adb679
added sig pick debug log
ChristianMct Apr 22, 2024
c24f65b
better retry mechanism and agOutRec
ChristianMct Apr 22, 2024
02dff7f
added server and client debug prints
ChristianMct Apr 22, 2024
264ad68
single mutex server
ChristianMct Apr 22, 2024
22182db
pretty print event logs and linter
ChristianMct Apr 22, 2024
cc9c8b1
not sending pd to completed circuits
ChristianMct Apr 22, 2024
bb3bc72
added starting prints to client
ChristianMct Apr 22, 2024
e9e44d3
attempt fix on executor registering
ChristianMct Apr 22, 2024
2a90505
running protocol descriptor directly update the connected node map
ChristianMct Apr 22, 2024
101d6b7
fix blocking share rcv at server
ChristianMct Apr 22, 2024
7014baa
changed stream closing sequence and added some debug output for regis…
ChristianMct Apr 22, 2024
5552bc1
fixing deadlock in executor
ChristianMct Apr 22, 2024
dd9dd37
re-fixing deadlock in executor
ChristianMct Apr 22, 2024
06c4db4
runAsAggregator must hold the connectedNode lock
ChristianMct Apr 22, 2024
61bfa83
fixes previous
ChristianMct Apr 22, 2024
a6c2026
reduced log volume
ChristianMct Apr 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

This file contains a log of the main changes made to the framework.

## [unrelease]

### Added
- CKKS-based sessions.
- Protocol retries.
- Generic coordination interface.

### Changed
- The `helium` package now provides the main entrypoint to the library, it now implementents the gRPC transport layer and node coordination, on top of the `node` package.
- The `sessions.Parameters` type now has an interface type field `FHEParameters` for specifiying the FHE scheme parameters. Currently,
`ckks.ParametersLiteral` and `bgv.ParametersLiteral` are supported.
- The `circuits.Runtime` interface now provide a single `EvalLocal` method for specifying local operations.


## [v0.1.0] - 15.03.2024
### Added
- First public `v0` release
46 changes: 29 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,17 @@ Here is an overview of an Helium application:
"mul-2-dec": func(rt circuits.Runtime) error {
in0, in1 := rt.Input("//p0/in"), rt.Input("//p1/in") // read the encrypted inputs from nodes p0 and p1

// multiplies the inputs
// multiplies the inputs as a local operation
opRes := rt.NewOperand("//eval/prod")
opRes.Ciphertext, _ = rt.MulRelinNew(in0.Get().Ciphertext, in1.Get().Ciphertext)
if err := rt.EvalLocal(
true, // circuit requires relin
nil, // circuit does not require any rotation
func(eval he.Evaluator) error {
return eval.MulRelin(in0.Get().Ciphertext, in1.Get().Ciphertext, opRes.Ciphertext)
}
); err != nil {
return err
}

// decrypts the result with receiver "rec"
return rt.DEC(opRes, "rec", map[string]string{
Expand All @@ -45,26 +53,30 @@ Here is an overview of an Helium application:
},
}

inputProvider = func(ctx context.Context, cid helium.CircuitID, ol circuits.OperandLabel, sess session.Session) (any, error) {
inputProvider = func(ctx context.Context, cid session.CircuitID, ol circuits.OperandLabel, sess session.Session) (any, error) {
// ... user-defined logic to provide input for a given circuit
}

ctx, config, nodelist := // ... (omitted config, usually loaded from files or command-line flags)

n, cdescs, outputs, err := node.RunNew(ctx, config, nodelist, app, inputProvider) // create an helium node that runs the app
if err != nil {
log.Fatal(err)
}

// cdesc is a channel to send circuit evaluation request(s)
cdescs <- circuits.Descriptor{
Signature: circuits.Signature{Name: circuits.Name("mul-4-dec")}, // evaluates circuit "mul-4-dec"
CircuitID: "mul-4-dec-0", // as circuit "mul-4-dec-0"
// ... other runtime-specific info
}

// outputs is a channel to recieve the evaluation(s) output(s)
out <- outputs
var cdescs chan<- circuit.Descriptor
var outs <-chan circuit.Output
if nodeID == helperID {
// the helper runs the server-side of helium
cdescs, outs, err = centralized.RunHeliumServer(ctx, config, nodelist, app, inputProvider)

// cdesc is a channel to send circuit evaluation request(s)
cdescs <- circuits.Descriptor{
Signature: circuits.Signature{Name: circuits.Name("mul-4-dec")}, // evaluates circuit "mul-4-dec"
CircuitID: "mul-4-dec-0", // as circuit "mul-4-dec-0"
// ... other runtime-specific info
}
} else {
// non-helper nodes run the client side
outs, err = centralized.RunHeliumClient(ctx, config, nodelist, app, inputProvider)
}
// outs is a channel to recieve the evaluation(s) output(s)
out <- outs
// ...
```

Expand Down
19 changes: 15 additions & 4 deletions transport/helium.proto → api/helium.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ package helium_proto;
aggregator and evaluator for its peer nodes. */
service Helium {
/* Register registers the caller as a peer node to the helium server */
rpc Register(Void) returns (stream Event);
rpc Register(Void) returns (stream NodeEvent);

/* PutShare pushes the caller's share in the protocol described by the Share.ShareDescriptor
field to the callee. */
Expand Down Expand Up @@ -71,9 +71,20 @@ message CircuitEvent {
EventType Type = 2;
}

message Event {
optional ProtocolEvent ProtocolEvent = 1;
optional CircuitEvent CircuitEvent = 2;
message SetupEvent {
ProtocolEvent ProtocolEvent = 1;
}

message ComputeEvent {
CircuitEvent CircuitEvent = 1;
optional ProtocolEvent ProtocolEvent = 2;
}

message NodeEvent {
oneof Event {
SetupEvent SetupEvent = 1;
ComputeEvent ComputeEvent = 2;
}
}


Expand Down
121 changes: 88 additions & 33 deletions transport/centralized/messages.go → api/messages.go
Original file line number Diff line number Diff line change
@@ -1,49 +1,104 @@
package centralized
// Package api implements a translation layer between the protobuf and internal Helium types.
package api

import (
"fmt"

"github.com/ChristianMct/helium"
"github.com/ChristianMct/helium/api/pb"
"github.com/ChristianMct/helium/circuits"
"github.com/ChristianMct/helium/coordinator"
"github.com/ChristianMct/helium/node"
"github.com/ChristianMct/helium/protocols"
"github.com/ChristianMct/helium/transport/pb"
"github.com/ChristianMct/helium/services/compute"
"github.com/ChristianMct/helium/services/setup"
"github.com/ChristianMct/helium/sessions"
"github.com/ChristianMct/helium/utils"
)

func getAPIEvent(event coordinator.Event) *pb.Event {
apiEvent := &pb.Event{}
func GetProtocolEvent(event protocols.Event) *pb.ProtocolEvent {
return &pb.ProtocolEvent{
Type: pb.EventType(event.EventType),
Descriptor_: GetProtocolDesc(&event.Descriptor),
}
}

func ToProtocolEvent(apiEvent *pb.ProtocolEvent) protocols.Event {
return protocols.Event{
EventType: protocols.EventType(apiEvent.Type),
Descriptor: *ToProtocolDesc(apiEvent.Descriptor_),
}
}

func GetSetupEvent(event setup.Event) *pb.SetupEvent {
return &pb.SetupEvent{
ProtocolEvent: GetProtocolEvent(event.Event),
}
}

func ToSetupEvent(apiEvent *pb.SetupEvent) setup.Event {
return setup.Event{
Event: ToProtocolEvent(apiEvent.ProtocolEvent),
}
}

func GetComputeEvent(event compute.Event) *pb.ComputeEvent {
apiEvent := &pb.ComputeEvent{}
if event.CircuitEvent != nil {
apiEvent.CircuitEvent = &pb.CircuitEvent{
Type: pb.EventType(event.CircuitEvent.EventType),
Descriptor_: getAPICircuitDesc(event.CircuitEvent.Descriptor),
Descriptor_: GetCircuitDesc(event.CircuitEvent.Descriptor),
}
}
if event.ProtocolEvent != nil {
apiDesc := getAPIProtocolDesc(&event.ProtocolEvent.Descriptor)
apiEvent.ProtocolEvent = &pb.ProtocolEvent{Type: pb.EventType(event.ProtocolEvent.EventType), Descriptor_: apiDesc}
apiEvent.ProtocolEvent = &pb.ProtocolEvent{
Type: pb.EventType(event.ProtocolEvent.EventType),
Descriptor_: GetProtocolDesc(&event.ProtocolEvent.Descriptor),
}
}
return apiEvent
}

func getEventFromAPI(apiEvent *pb.Event) coordinator.Event {
event := coordinator.Event{}
func ToComputeEvent(apiEvent *pb.ComputeEvent) compute.Event {
event := compute.Event{}
if apiEvent.CircuitEvent != nil {
event.CircuitEvent = &circuits.Event{
EventType: circuits.EventType(apiEvent.CircuitEvent.Type),
Descriptor: *getCircuitDescFromAPI(apiEvent.CircuitEvent.Descriptor_),
Descriptor: *ToCircuitDesc(apiEvent.CircuitEvent.Descriptor_),
}
}
if apiEvent.ProtocolEvent != nil {
event.ProtocolEvent = &protocols.Event{
EventType: protocols.EventType(apiEvent.ProtocolEvent.Type),
Descriptor: *getProtocolDescFromAPI(apiEvent.ProtocolEvent.Descriptor_),
Descriptor: *ToProtocolDesc(apiEvent.ProtocolEvent.Descriptor_),
}
}
return event
}

func getAPIProtocolDesc(pd *protocols.Descriptor) *pb.ProtocolDescriptor {
func GetNodeEvent(event node.Event) *pb.NodeEvent {
apiEvent := &pb.NodeEvent{}
if event.IsSetup() {
apiEvent.Event = &pb.NodeEvent_SetupEvent{SetupEvent: GetSetupEvent(*event.SetupEvent)}
}
if event.IsCompute() {
apiEvent.Event = &pb.NodeEvent_ComputeEvent{ComputeEvent: GetComputeEvent(*event.ComputeEvent)}
}
return apiEvent
}

func ToNodeEvent(apiEvent *pb.NodeEvent) node.Event {
event := node.Event{}
switch e := apiEvent.Event.(type) {
case *pb.NodeEvent_SetupEvent:
ev := ToSetupEvent(e.SetupEvent)
event.SetupEvent = &ev
case *pb.NodeEvent_ComputeEvent:
ev := ToComputeEvent(e.ComputeEvent)
event.ComputeEvent = &ev
}
return event
}

func GetProtocolDesc(pd *protocols.Descriptor) *pb.ProtocolDescriptor {
apiDesc := &pb.ProtocolDescriptor{
ProtocolType: pb.ProtocolType(pd.Signature.Type),
Args: make(map[string]string, len(pd.Signature.Args)),
Expand All @@ -59,22 +114,22 @@ func getAPIProtocolDesc(pd *protocols.Descriptor) *pb.ProtocolDescriptor {
return apiDesc
}

func getProtocolDescFromAPI(apiPD *pb.ProtocolDescriptor) *protocols.Descriptor {
func ToProtocolDesc(apiPD *pb.ProtocolDescriptor) *protocols.Descriptor {
desc := &protocols.Descriptor{
Signature: protocols.Signature{Type: protocols.Type(apiPD.ProtocolType), Args: make(map[string]string)},
Aggregator: helium.NodeID(apiPD.Aggregator.NodeId),
Participants: make([]helium.NodeID, 0, len(apiPD.Participants)),
Aggregator: sessions.NodeID(apiPD.Aggregator.NodeId),
Participants: make([]sessions.NodeID, 0, len(apiPD.Participants)),
}
for k, v := range apiPD.Args {
desc.Signature.Args[k] = v
}
for _, p := range apiPD.Participants {
desc.Participants = append(desc.Participants, helium.NodeID(p.NodeId))
desc.Participants = append(desc.Participants, sessions.NodeID(p.NodeId))
}
return desc
}

func getAPICircuitDesc(cd circuits.Descriptor) *pb.CircuitDescriptor {
func GetCircuitDesc(cd circuits.Descriptor) *pb.CircuitDescriptor {
apiDesc := &pb.CircuitDescriptor{
CircuitSignature: &pb.CircuitSignature{
Name: string(cd.Name),
Expand All @@ -96,29 +151,29 @@ func getAPICircuitDesc(cd circuits.Descriptor) *pb.CircuitDescriptor {
return apiDesc
}

func getCircuitDescFromAPI(apiCd *pb.CircuitDescriptor) *circuits.Descriptor {
func ToCircuitDesc(apiCd *pb.CircuitDescriptor) *circuits.Descriptor {
cd := &circuits.Descriptor{
Signature: circuits.Signature{
Name: circuits.Name(apiCd.CircuitSignature.Name),
Args: make(map[string]string, len(apiCd.CircuitSignature.Args)),
},
CircuitID: helium.CircuitID(apiCd.CircuitID.CircuitID),
NodeMapping: make(map[string]helium.NodeID, len(apiCd.NodeMapping)),
Evaluator: helium.NodeID(apiCd.Evaluator.NodeId),
CircuitID: sessions.CircuitID(apiCd.CircuitID.CircuitID),
NodeMapping: make(map[string]sessions.NodeID, len(apiCd.NodeMapping)),
Evaluator: sessions.NodeID(apiCd.Evaluator.NodeId),
}

for k, v := range apiCd.CircuitSignature.Args {
cd.Args[k] = v
}

for s, nid := range apiCd.NodeMapping {
cd.NodeMapping[s] = helium.NodeID(nid.NodeId)
cd.NodeMapping[s] = sessions.NodeID(nid.NodeId)
}

return cd
}

func getAPIShare(s *protocols.Share) (*pb.Share, error) {
func GetShare(s *protocols.Share) (*pb.Share, error) {
outShareBytes, err := s.MarshalBinary()
if err != nil {
return nil, err
Expand All @@ -137,7 +192,7 @@ func getAPIShare(s *protocols.Share) (*pb.Share, error) {
return apiShare, nil
}

func getShareFromAPI(s *pb.Share) (protocols.Share, error) {
func ToShare(s *pb.Share) (protocols.Share, error) {
desc := s.GetMetadata()
pID := protocols.ID(desc.GetProtocolID().GetProtocolID())
pType := protocols.Type(desc.ProtocolType)
Expand All @@ -149,12 +204,12 @@ func getShareFromAPI(s *pb.Share) (protocols.Share, error) {
ShareMetadata: protocols.ShareMetadata{
ProtocolID: pID,
ProtocolType: pType,
From: make(utils.Set[helium.NodeID]),
From: make(utils.Set[sessions.NodeID]),
},
MHEShare: share,
}
for _, nid := range desc.AggregateFor {
ps.From.Add(helium.NodeID(nid.NodeId))
ps.From.Add(sessions.NodeID(nid.NodeId))
}

err := ps.MHEShare.UnmarshalBinary(s.GetShare())
Expand All @@ -164,7 +219,7 @@ func getShareFromAPI(s *pb.Share) (protocols.Share, error) {
return ps, nil
}

func getAPICiphertext(ct *helium.Ciphertext) (*pb.Ciphertext, error) {
func GetCiphertext(ct *sessions.Ciphertext) (*pb.Ciphertext, error) {
ctBytes, err := ct.MarshalBinary()
if err != nil {
return nil, err
Expand All @@ -176,10 +231,10 @@ func getAPICiphertext(ct *helium.Ciphertext) (*pb.Ciphertext, error) {
}, nil
}

func getCiphertextFromAPI(apiCt *pb.Ciphertext) (*helium.Ciphertext, error) {
var ct helium.Ciphertext
ct.CiphertextMetadata.ID = helium.CiphertextID(apiCt.Metadata.GetId().CiphertextId)
ct.CiphertextMetadata.Type = helium.CiphertextType(apiCt.Metadata.GetType())
func ToCiphertext(apiCt *pb.Ciphertext) (*sessions.Ciphertext, error) {
var ct sessions.Ciphertext
ct.CiphertextMetadata.ID = sessions.CiphertextID(apiCt.Metadata.GetId().CiphertextId)
ct.CiphertextMetadata.Type = sessions.CiphertextType(apiCt.Metadata.GetType())
err := ct.Ciphertext.UnmarshalBinary(apiCt.Ciphertext)
if err != nil {
return nil, err
Expand Down
Loading
Loading