diff --git a/.nil-sdk.toml b/.nil-sdk.toml index 5e6e5475..386459cf 100644 --- a/.nil-sdk.toml +++ b/.nil-sdk.toml @@ -1 +1 @@ -version = "v0.9.0-rc.61" +version = "v0.10.0-rc.32" diff --git a/client-vms/src/gen-proto/nillion/compute/v1/stream_pb.ts b/client-vms/src/gen-proto/nillion/compute/v1/stream_pb.ts index 14a4f543..5e0aca83 100644 --- a/client-vms/src/gen-proto/nillion/compute/v1/stream_pb.ts +++ b/client-vms/src/gen-proto/nillion/compute/v1/stream_pb.ts @@ -10,7 +10,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file nillion/compute/v1/stream.proto. */ export const file_nillion_compute_v1_stream: GenFile = /*@__PURE__*/ - fileDesc("Ch9uaWxsaW9uL2NvbXB1dGUvdjEvc3RyZWFtLnByb3RvEhluaWxsaW9uLmNvbXB1dGUudjEuc3RyZWFtIoEBChRDb21wdXRlU3RyZWFtTWVzc2FnZRISCgpjb21wdXRlX2lkGAEgASgMEhcKD2JpbmNvZGVfbWVzc2FnZRgCIAEoDBI8Cgxjb21wdXRlX3R5cGUYAyABKA4yJi5uaWxsaW9uLmNvbXB1dGUudjEuc3RyZWFtLkNvbXB1dGVUeXBlKikKC0NvbXB1dGVUeXBlEgsKB0dFTkVSQUwQABINCglFQ0RTQV9ES0cQAUK0AQodY29tLm5pbGxpb24uY29tcHV0ZS52MS5zdHJlYW1CC1N0cmVhbVByb3RvUAGiAgROQ1ZTqgIZTmlsbGlvbi5Db21wdXRlLlYxLlN0cmVhbcoCGU5pbGxpb25cQ29tcHV0ZVxWMVxTdHJlYW3iAiVOaWxsaW9uXENvbXB1dGVcVjFcU3RyZWFtXEdQQk1ldGFkYXRh6gIcTmlsbGlvbjo6Q29tcHV0ZTo6VjE6OlN0cmVhbWIGcHJvdG8z"); + fileDesc("Ch9uaWxsaW9uL2NvbXB1dGUvdjEvc3RyZWFtLnByb3RvEhluaWxsaW9uLmNvbXB1dGUudjEuc3RyZWFtIoEBChRDb21wdXRlU3RyZWFtTWVzc2FnZRISCgpjb21wdXRlX2lkGAEgASgMEhcKD2JpbmNvZGVfbWVzc2FnZRgCIAEoDBI8Cgxjb21wdXRlX3R5cGUYAyABKA4yJi5uaWxsaW9uLmNvbXB1dGUudjEuc3RyZWFtLkNvbXB1dGVUeXBlKjgKC0NvbXB1dGVUeXBlEgsKB0dFTkVSQUwQABINCglFQ0RTQV9ES0cQARINCglFRERTQV9ES0cQAkK0AQodY29tLm5pbGxpb24uY29tcHV0ZS52MS5zdHJlYW1CC1N0cmVhbVByb3RvUAGiAgROQ1ZTqgIZTmlsbGlvbi5Db21wdXRlLlYxLlN0cmVhbcoCGU5pbGxpb25cQ29tcHV0ZVxWMVxTdHJlYW3iAiVOaWxsaW9uXENvbXB1dGVcVjFcU3RyZWFtXEdQQk1ldGFkYXRh6gIcTmlsbGlvbjo6Q29tcHV0ZTo6VjE6OlN0cmVhbWIGcHJvdG8z"); /** * A message for a compute stream. @@ -51,9 +51,10 @@ export const ComputeStreamMessageSchema: GenMessage = /*@_ messageDesc(file_nillion_compute_v1_stream, 0); /** - * The type of compute performed. We currently support two types: + * The type of compute performed. We currently support three types: * - GENERAL: A general compute that computes some Nada program. * - ECDSA_DKG: A specific compute operation for ECDSA distributed key generation. + * - EDDSA_DKG: A specific compute operation for Eddsa distributed key generation. * * @generated from enum nillion.compute.v1.stream.ComputeType */ @@ -71,6 +72,13 @@ export enum ComputeType { * @generated from enum value: ECDSA_DKG = 1; */ ECDSA_DKG = 1, + + /** + * An Eddsa distributed key generation protocol. + * + * @generated from enum value: EDDSA_DKG = 2; + */ + EDDSA_DKG = 2, } /** diff --git a/client-vms/src/gen-proto/nillion/values/v1/value_pb.ts b/client-vms/src/gen-proto/nillion/values/v1/value_pb.ts index 8cab0c0d..588abe22 100644 --- a/client-vms/src/gen-proto/nillion/values/v1/value_pb.ts +++ b/client-vms/src/gen-proto/nillion/values/v1/value_pb.ts @@ -12,7 +12,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file nillion/values/v1/value.proto. */ export const file_nillion_values_v1_value: GenFile = /*@__PURE__*/ - fileDesc("Ch1uaWxsaW9uL3ZhbHVlcy92MS92YWx1ZS5wcm90bxIXbmlsbGlvbi52YWx1ZXMudjEudmFsdWUiSQoKTmFtZWRWYWx1ZRIMCgRuYW1lGAEgASgJEi0KBXZhbHVlGAIgASgLMh4ubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuVmFsdWUizgcKBVZhbHVlEkAKDnB1YmxpY19ib29sZWFuGAEgASgLMiYubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuUHVibGljSW50ZWdlckgAEkAKDnB1YmxpY19pbnRlZ2VyGAIgASgLMiYubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuUHVibGljSW50ZWdlckgAEkkKF3B1YmxpY191bnNpZ25lZF9pbnRlZ2VyGAMgASgLMiYubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuUHVibGljSW50ZWdlckgAEkQKFHNoYW1pcl9zaGFyZV9ib29sZWFuGAQgASgLMiQubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuU2hhbWlyU2hhcmVIABJEChRzaGFtaXJfc2hhcmVfaW50ZWdlchgFIAEoCzIkLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLlNoYW1pclNoYXJlSAASTQodc2hhbWlyX3NoYXJlX3Vuc2lnbmVkX2ludGVnZXIYBiABKAsyJC5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5TaGFtaXJTaGFyZUgAEi8KBWFycmF5GAcgASgLMh4ubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuQXJyYXlIABIvCgV0dXBsZRgIIAEoCzIeLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLlR1cGxlSAASRwoSc2hhbWlyX3NoYXJlc19ibG9iGAkgASgLMikubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuU2hhbWlyU2hhcmVzQmxvYkgAElAKF2VjZHNhX3ByaXZhdGVfa2V5X3NoYXJlGAogASgLMi0ubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuRWNkc2FQcml2YXRlS2V5U2hhcmVIABJNChVlY2RzYV9zaWduYXR1cmVfc2hhcmUYCyABKAsyLC5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5FY2RzYVNpZ25hdHVyZVNoYXJlSAASSwoUZWNkc2FfbWVzc2FnZV9kaWdlc3QYDCABKAsyKy5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5FY2RzYU1lc3NhZ2VEaWdlc3RIABJDChBlY2RzYV9wdWJsaWNfa2V5GA0gASgLMicubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuRWNkc2FQdWJsaWNLZXlIABI0CghzdG9yZV9pZBgOIAEoCzIgLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLlN0b3JlSWRIAEIHCgV2YWx1ZSIeCg1QdWJsaWNJbnRlZ2VyEg0KBXZhbHVlGAEgASgMIhwKC1NoYW1pclNoYXJlEg0KBXZhbHVlGAEgASgMIm8KBUFycmF5Ei4KBnZhbHVlcxgBIAMoCzIeLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLlZhbHVlEjYKCmlubmVyX3R5cGUYAiABKAsyIi5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5WYWx1ZVR5cGUiZAoFVHVwbGUSLAoEbGVmdBgBIAEoCzIeLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLlZhbHVlEi0KBXJpZ2h0GAIgASgLMh4ubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuVmFsdWUiXgoURWNkc2FQcml2YXRlS2V5U2hhcmUSCQoBaRgBIAEoDRIJCgF4GAIgASgMEhkKEXNoYXJlZF9wdWJsaWNfa2V5GAMgASgMEhUKDXB1YmxpY19zaGFyZXMYBCADKAwiLwoTRWNkc2FTaWduYXR1cmVTaGFyZRIJCgFyGAEgASgMEg0KBXNpZ21hGAIgASgMIiQKEkVjZHNhTWVzc2FnZURpZ2VzdBIOCgZkaWdlc3QYASABKAwiJAoORWNkc2FQdWJsaWNLZXkSEgoKcHVibGljX2tleRgBIAEoDCIbCgdTdG9yZUlkEhAKCHN0b3JlX2lkGAEgASgMIl8KEFNoYW1pclNoYXJlc0Jsb2ISNAoGc2hhcmVzGAEgAygLMiQubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuU2hhbWlyU2hhcmUSFQoNb3JpZ2luYWxfc2l6ZRgCIAEoBCLfBQoJVmFsdWVUeXBlEjAKDnB1YmxpY19pbnRlZ2VyGAEgASgLMhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5SAASOQoXcHVibGljX3Vuc2lnbmVkX2ludGVnZXIYAiABKAsyFi5nb29nbGUucHJvdG9idWYuRW1wdHlIABIwCg5wdWJsaWNfYm9vbGVhbhgDIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEjYKFHNoYW1pcl9zaGFyZV9pbnRlZ2VyGAQgASgLMhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5SAASPwodc2hhbWlyX3NoYXJlX3Vuc2lnbmVkX2ludGVnZXIYBSABKAsyFi5nb29nbGUucHJvdG9idWYuRW1wdHlIABI2ChRzaGFtaXJfc2hhcmVfYm9vbGVhbhgGIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEjMKBWFycmF5GAcgASgLMiIubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuQXJyYXlUeXBlSAASMwoFdHVwbGUYCCABKAsyIi5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5UdXBsZVR5cGVIABI5ChdlY2RzYV9wcml2YXRlX2tleV9zaGFyZRgJIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEjYKFGVjZHNhX21lc3NhZ2VfZGlnZXN0GAogASgLMhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5SAASNwoVZWNkc2Ffc2lnbmF0dXJlX3NoYXJlGAsgASgLMhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5SAASMgoQZWNkc2FfcHVibGljX2tleRgMIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEioKCHN0b3JlX2lkGA0gASgLMhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5SABCDAoKdmFsdWVfdHlwZSJRCglBcnJheVR5cGUSNgoKaW5uZXJfdHlwZRgBIAEoCzIiLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLlZhbHVlVHlwZRIMCgRzaXplGAIgASgEInAKCVR1cGxlVHlwZRIwCgRsZWZ0GAEgASgLMiIubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuVmFsdWVUeXBlEjEKBXJpZ2h0GAIgASgLMiIubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuVmFsdWVUeXBlQqkBChtjb20ubmlsbGlvbi52YWx1ZXMudjEudmFsdWVCClZhbHVlUHJvdG9QAaICBE5WVlaqAhdOaWxsaW9uLlZhbHVlcy5WMS5WYWx1ZcoCF05pbGxpb25cVmFsdWVzXFYxXFZhbHVl4gIjTmlsbGlvblxWYWx1ZXNcVjFcVmFsdWVcR1BCTWV0YWRhdGHqAhpOaWxsaW9uOjpWYWx1ZXM6OlYxOjpWYWx1ZWIGcHJvdG8z", [file_google_protobuf_empty]); + fileDesc("Ch1uaWxsaW9uL3ZhbHVlcy92MS92YWx1ZS5wcm90bxIXbmlsbGlvbi52YWx1ZXMudjEudmFsdWUiSQoKTmFtZWRWYWx1ZRIMCgRuYW1lGAEgASgJEi0KBXZhbHVlGAIgASgLMh4ubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuVmFsdWUi6QkKBVZhbHVlEkAKDnB1YmxpY19ib29sZWFuGAEgASgLMiYubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuUHVibGljSW50ZWdlckgAEkAKDnB1YmxpY19pbnRlZ2VyGAIgASgLMiYubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuUHVibGljSW50ZWdlckgAEkkKF3B1YmxpY191bnNpZ25lZF9pbnRlZ2VyGAMgASgLMiYubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuUHVibGljSW50ZWdlckgAEkQKFHNoYW1pcl9zaGFyZV9ib29sZWFuGAQgASgLMiQubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuU2hhbWlyU2hhcmVIABJEChRzaGFtaXJfc2hhcmVfaW50ZWdlchgFIAEoCzIkLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLlNoYW1pclNoYXJlSAASTQodc2hhbWlyX3NoYXJlX3Vuc2lnbmVkX2ludGVnZXIYBiABKAsyJC5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5TaGFtaXJTaGFyZUgAEi8KBWFycmF5GAcgASgLMh4ubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuQXJyYXlIABIvCgV0dXBsZRgIIAEoCzIeLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLlR1cGxlSAASRwoSc2hhbWlyX3NoYXJlc19ibG9iGAkgASgLMikubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuU2hhbWlyU2hhcmVzQmxvYkgAElAKF2VjZHNhX3ByaXZhdGVfa2V5X3NoYXJlGAogASgLMi0ubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuRWNkc2FQcml2YXRlS2V5U2hhcmVIABJNChVlY2RzYV9zaWduYXR1cmVfc2hhcmUYCyABKAsyLC5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5FY2RzYVNpZ25hdHVyZVNoYXJlSAASSwoUZWNkc2FfbWVzc2FnZV9kaWdlc3QYDCABKAsyKy5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5FY2RzYU1lc3NhZ2VEaWdlc3RIABJDChBlY2RzYV9wdWJsaWNfa2V5GA0gASgLMicubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuRWNkc2FQdWJsaWNLZXlIABI0CghzdG9yZV9pZBgOIAEoCzIgLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLlN0b3JlSWRIABJQChdlZGRzYV9wcml2YXRlX2tleV9zaGFyZRgPIAEoCzItLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLkVkZHNhUHJpdmF0ZUtleVNoYXJlSAASQgoPZWRkc2Ffc2lnbmF0dXJlGBAgASgLMicubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuRWRkc2FTaWduYXR1cmVIABI+Cg1lZGRzYV9tZXNzYWdlGBEgASgLMiUubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuRWRkc2FNZXNzYWdlSAASQwoQZWRkc2FfcHVibGljX2tleRgSIAEoCzInLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLkVkZHNhUHVibGljS2V5SABCBwoFdmFsdWUiHgoNUHVibGljSW50ZWdlchINCgV2YWx1ZRgBIAEoDCIcCgtTaGFtaXJTaGFyZRINCgV2YWx1ZRgBIAEoDCJvCgVBcnJheRIuCgZ2YWx1ZXMYASADKAsyHi5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5WYWx1ZRI2Cgppbm5lcl90eXBlGAIgASgLMiIubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuVmFsdWVUeXBlImQKBVR1cGxlEiwKBGxlZnQYASABKAsyHi5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5WYWx1ZRItCgVyaWdodBgCIAEoCzIeLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLlZhbHVlIl4KFEVjZHNhUHJpdmF0ZUtleVNoYXJlEgkKAWkYASABKA0SCQoBeBgCIAEoDBIZChFzaGFyZWRfcHVibGljX2tleRgDIAEoDBIVCg1wdWJsaWNfc2hhcmVzGAQgAygMIi8KE0VjZHNhU2lnbmF0dXJlU2hhcmUSCQoBchgBIAEoDBINCgVzaWdtYRgCIAEoDCIkChJFY2RzYU1lc3NhZ2VEaWdlc3QSDgoGZGlnZXN0GAEgASgMIiQKDkVjZHNhUHVibGljS2V5EhIKCnB1YmxpY19rZXkYASABKAwiGwoHU3RvcmVJZBIQCghzdG9yZV9pZBgBIAEoDCJeChRFZGRzYVByaXZhdGVLZXlTaGFyZRIJCgFpGAEgASgNEgkKAXgYAiABKAwSGQoRc2hhcmVkX3B1YmxpY19rZXkYAyABKAwSFQoNcHVibGljX3NoYXJlcxgEIAMoDCIjCg5FZGRzYVNpZ25hdHVyZRIRCglzaWduYXR1cmUYASABKAwiHwoMRWRkc2FNZXNzYWdlEg8KB21lc3NhZ2UYASABKAwiJAoORWRkc2FQdWJsaWNLZXkSEgoKcHVibGljX2tleRgBIAEoDCJfChBTaGFtaXJTaGFyZXNCbG9iEjQKBnNoYXJlcxgBIAMoCzIkLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLlNoYW1pclNoYXJlEhUKDW9yaWdpbmFsX3NpemUYAiABKAQisgcKCVZhbHVlVHlwZRIwCg5wdWJsaWNfaW50ZWdlchgBIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEjkKF3B1YmxpY191bnNpZ25lZF9pbnRlZ2VyGAIgASgLMhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5SAASMAoOcHVibGljX2Jvb2xlYW4YAyABKAsyFi5nb29nbGUucHJvdG9idWYuRW1wdHlIABI2ChRzaGFtaXJfc2hhcmVfaW50ZWdlchgEIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEj8KHXNoYW1pcl9zaGFyZV91bnNpZ25lZF9pbnRlZ2VyGAUgASgLMhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5SAASNgoUc2hhbWlyX3NoYXJlX2Jvb2xlYW4YBiABKAsyFi5nb29nbGUucHJvdG9idWYuRW1wdHlIABIzCgVhcnJheRgHIAEoCzIiLm5pbGxpb24udmFsdWVzLnYxLnZhbHVlLkFycmF5VHlwZUgAEjMKBXR1cGxlGAggASgLMiIubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuVHVwbGVUeXBlSAASOQoXZWNkc2FfcHJpdmF0ZV9rZXlfc2hhcmUYCSABKAsyFi5nb29nbGUucHJvdG9idWYuRW1wdHlIABI2ChRlY2RzYV9tZXNzYWdlX2RpZ2VzdBgKIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEjcKFWVjZHNhX3NpZ25hdHVyZV9zaGFyZRgLIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEjIKEGVjZHNhX3B1YmxpY19rZXkYDCABKAsyFi5nb29nbGUucHJvdG9idWYuRW1wdHlIABIqCghzdG9yZV9pZBgNIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEjkKF2VkZHNhX3ByaXZhdGVfa2V5X3NoYXJlGA4gASgLMhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5SAASMQoPZWRkc2Ffc2lnbmF0dXJlGA8gASgLMhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5SAASLwoNZWRkc2FfbWVzc2FnZRgQIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEjIKEGVkZHNhX3B1YmxpY19rZXkYESABKAsyFi5nb29nbGUucHJvdG9idWYuRW1wdHlIAEIMCgp2YWx1ZV90eXBlIlEKCUFycmF5VHlwZRI2Cgppbm5lcl90eXBlGAEgASgLMiIubmlsbGlvbi52YWx1ZXMudjEudmFsdWUuVmFsdWVUeXBlEgwKBHNpemUYAiABKAQicAoJVHVwbGVUeXBlEjAKBGxlZnQYASABKAsyIi5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5WYWx1ZVR5cGUSMQoFcmlnaHQYAiABKAsyIi5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZS5WYWx1ZVR5cGVCqQEKG2NvbS5uaWxsaW9uLnZhbHVlcy52MS52YWx1ZUIKVmFsdWVQcm90b1ABogIETlZWVqoCF05pbGxpb24uVmFsdWVzLlYxLlZhbHVlygIXTmlsbGlvblxWYWx1ZXNcVjFcVmFsdWXiAiNOaWxsaW9uXFZhbHVlc1xWMVxWYWx1ZVxHUEJNZXRhZGF0YeoCGk5pbGxpb246OlZhbHVlczo6VjE6OlZhbHVlYgZwcm90bzM", [file_google_protobuf_empty]); /** * A named value. @@ -163,6 +163,38 @@ export type Value = Message<"nillion.values.v1.value.Value"> & { */ value: StoreId; case: "storeId"; + } | { + /** + * An Eddsa private key share. + * + * @generated from field: nillion.values.v1.value.EddsaPrivateKeyShare eddsa_private_key_share = 15; + */ + value: EddsaPrivateKeyShare; + case: "eddsaPrivateKeyShare"; + } | { + /** + * An Eddsa signature. + * + * @generated from field: nillion.values.v1.value.EddsaSignature eddsa_signature = 16; + */ + value: EddsaSignature; + case: "eddsaSignature"; + } | { + /** + * An Eddsa message. + * + * @generated from field: nillion.values.v1.value.EddsaMessage eddsa_message = 17; + */ + value: EddsaMessage; + case: "eddsaMessage"; + } | { + /** + * An Eddsa public key. + * + * @generated from field: nillion.values.v1.value.EddsaPublicKey eddsa_public_key = 18; + */ + value: EddsaPublicKey; + case: "eddsaPublicKey"; } | { case: undefined; value?: undefined }; }; @@ -406,6 +438,111 @@ export type StoreId = Message<"nillion.values.v1.value.StoreId"> & { export const StoreIdSchema: GenMessage = /*@__PURE__*/ messageDesc(file_nillion_values_v1_value, 10); +/** + * An Eddsa private key share. + * + * @generated from message nillion.values.v1.value.EddsaPrivateKeyShare + */ +export type EddsaPrivateKeyShare = Message<"nillion.values.v1.value.EddsaPrivateKeyShare"> & { + /** + * Index of local party in key generation protocol. + * + * @generated from field: uint32 i = 1; + */ + i: number; + + /** + * The secret share x. + * + * @generated from field: bytes x = 2; + */ + x: Uint8Array; + + /** + * Public key corresponding to shared secret key, in compressed form. + * + * @generated from field: bytes shared_public_key = 3; + */ + sharedPublicKey: Uint8Array; + + /** + * Public shares of all signers sharing the key, in compressed form. + * + * @generated from field: repeated bytes public_shares = 4; + */ + publicShares: Uint8Array[]; +}; + +/** + * Describes the message nillion.values.v1.value.EddsaPrivateKeyShare. + * Use `create(EddsaPrivateKeyShareSchema)` to create a new message. + */ +export const EddsaPrivateKeyShareSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_nillion_values_v1_value, 11); + +/** + * An Eddsa signature. + * + * @generated from message nillion.values.v1.value.EddsaSignature + */ +export type EddsaSignature = Message<"nillion.values.v1.value.EddsaSignature"> & { + /** + * The signature. + * + * @generated from field: bytes signature = 1; + */ + signature: Uint8Array; +}; + +/** + * Describes the message nillion.values.v1.value.EddsaSignature. + * Use `create(EddsaSignatureSchema)` to create a new message. + */ +export const EddsaSignatureSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_nillion_values_v1_value, 12); + +/** + * An Eddsa message. + * + * @generated from message nillion.values.v1.value.EddsaMessage + */ +export type EddsaMessage = Message<"nillion.values.v1.value.EddsaMessage"> & { + /** + * The message. + * + * @generated from field: bytes message = 1; + */ + message: Uint8Array; +}; + +/** + * Describes the message nillion.values.v1.value.EddsaMessage. + * Use `create(EddsaMessageSchema)` to create a new message. + */ +export const EddsaMessageSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_nillion_values_v1_value, 13); + +/** + * An Eddsa public key. + * + * @generated from message nillion.values.v1.value.EddsaPublicKey + */ +export type EddsaPublicKey = Message<"nillion.values.v1.value.EddsaPublicKey"> & { + /** + * The public key. + * + * @generated from field: bytes public_key = 1; + */ + publicKey: Uint8Array; +}; + +/** + * Describes the message nillion.values.v1.value.EddsaPublicKey. + * Use `create(EddsaPublicKeySchema)` to create a new message. + */ +export const EddsaPublicKeySchema: GenMessage = /*@__PURE__*/ + messageDesc(file_nillion_values_v1_value, 14); + /** * Shamir shares of a blob. * @@ -432,7 +569,7 @@ export type ShamirSharesBlob = Message<"nillion.values.v1.value.ShamirSharesBlob * Use `create(ShamirSharesBlobSchema)` to create a new message. */ export const ShamirSharesBlobSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nillion_values_v1_value, 11); + messageDesc(file_nillion_values_v1_value, 15); /** * A type of a value. @@ -547,6 +684,38 @@ export type ValueType = Message<"nillion.values.v1.value.ValueType"> & { */ value: Empty; case: "storeId"; + } | { + /** + * An Eddsa private key share. + * + * @generated from field: google.protobuf.Empty eddsa_private_key_share = 14; + */ + value: Empty; + case: "eddsaPrivateKeyShare"; + } | { + /** + * An Eddsa signature. + * + * @generated from field: google.protobuf.Empty eddsa_signature = 15; + */ + value: Empty; + case: "eddsaSignature"; + } | { + /** + * An Eddsa message. + * + * @generated from field: google.protobuf.Empty eddsa_message = 16; + */ + value: Empty; + case: "eddsaMessage"; + } | { + /** + * An Eddsa public key. + * + * @generated from field: google.protobuf.Empty eddsa_public_key = 17; + */ + value: Empty; + case: "eddsaPublicKey"; } | { case: undefined; value?: undefined }; }; @@ -555,7 +724,7 @@ export type ValueType = Message<"nillion.values.v1.value.ValueType"> & { * Use `create(ValueTypeSchema)` to create a new message. */ export const ValueTypeSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nillion_values_v1_value, 12); + messageDesc(file_nillion_values_v1_value, 16); /** * An array. @@ -583,7 +752,7 @@ export type ArrayType = Message<"nillion.values.v1.value.ArrayType"> & { * Use `create(ArrayTypeSchema)` to create a new message. */ export const ArrayTypeSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nillion_values_v1_value, 13); + messageDesc(file_nillion_values_v1_value, 17); /** * A tuple. @@ -611,5 +780,5 @@ export type TupleType = Message<"nillion.values.v1.value.TupleType"> & { * Use `create(TupleTypeSchema)` to create a new message. */ export const TupleTypeSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nillion_values_v1_value, 14); + messageDesc(file_nillion_values_v1_value, 18); diff --git a/client-vms/src/types/types.ts b/client-vms/src/types/types.ts index 5d12366e..ed3090b8 100644 --- a/client-vms/src/types/types.ts +++ b/client-vms/src/types/types.ts @@ -1,5 +1,9 @@ import { type Timestamp, timestampDate } from "@bufbuild/protobuf/wkt"; -import { EcdsaSignature, PartyId as WasmPartyId } from "@nillion/client-wasm"; +import { + EcdsaSignature, + EddsaSignature, + PartyId as WasmPartyId, +} from "@nillion/client-wasm"; import { z } from "zod"; import type { PriceQuoteRequest, @@ -89,6 +93,7 @@ export const NadaValuesRecord = z.record( z.string(), z.instanceof(Uint8Array), z.instanceof(EcdsaSignature), + z.instanceof(EddsaSignature), ]), }), ); @@ -138,6 +143,25 @@ export const EncryptedNadaValueRecord = z.discriminatedUnion("type", [ type: z.literal("EcdsaPublicKey"), publicKey: z.instanceof(Uint8Array), }), + z.object({ + type: z.literal("EddsaMessage"), + message: z.instanceof(Uint8Array), + }), + z.object({ + type: z.literal("EddsaPrivateKey"), + i: z.string(), + x: z.instanceof(Uint8Array), + sharedPublicKey: z.instanceof(Uint8Array), + publicShares: z.array(z.instanceof(Uint8Array)), + }), + z.object({ + type: z.literal("EddsaSignature"), + signature: z.instanceof(Uint8Array), + }), + z.object({ + type: z.literal("EddsaPublicKey"), + publicKey: z.instanceof(Uint8Array), + }), z.object({ type: z.literal("StoreId"), storeId: z.instanceof(Uint8Array), diff --git a/client-vms/src/vm/builder.ts b/client-vms/src/vm/builder.ts index 5f8b1d90..213598d8 100644 --- a/client-vms/src/vm/builder.ts +++ b/client-vms/src/vm/builder.ts @@ -15,7 +15,7 @@ import { PaymentClientBuilder, PaymentMode } from "#/payment"; import { PartyId, UserId } from "#/types"; import { OfflineSignerSchema } from "#/types/grpc"; import { assertIsDefined, unwrapExceptionCause } from "#/util"; -import { createGrpcTransport, VmClient, VmClientConfig } from "#/vm/client"; +import { VmClient, VmClientConfig, createGrpcTransport } from "#/vm/client"; export const VmClientBuilderConfig = z.object({ bootnodeUrl: z.string().url("Invalid bootnode url"), diff --git a/client-vms/src/vm/client.ts b/client-vms/src/vm/client.ts index 58e06d61..70c9a4af 100644 --- a/client-vms/src/vm/client.ts +++ b/client-vms/src/vm/client.ts @@ -1,3 +1,4 @@ +import type { Interceptor, Transport } from "@connectrpc/connect"; import { SecretMasker } from "@nillion/client-wasm"; import { z } from "zod"; import { PaymentClient } from "#/payment"; @@ -14,7 +15,6 @@ import { StoreValuesBuilder, UpdatePermissionsBuilder, } from "./operation"; -import type { Interceptor, Transport } from "@connectrpc/connect"; /** * Configuration for communicating with a Nillion network node. diff --git a/client-vms/src/vm/values.ts b/client-vms/src/vm/values.ts index eb686d5a..605f0a78 100644 --- a/client-vms/src/vm/values.ts +++ b/client-vms/src/vm/values.ts @@ -5,6 +5,10 @@ import { EcdsaPrivateKeyShareSchema, EcdsaPublicKeySchema, EcdsaSignatureShareSchema, + EddsaMessageSchema, + EddsaPrivateKeyShareSchema, + EddsaPublicKeySchema, + EddsaSignatureSchema, type NamedValue, NamedValueSchema, PublicIntegerSchema, @@ -56,13 +60,6 @@ function nadaValueToProto(nadaValue: EncryptedNadaValueRecord): Value { value: create(PublicIntegerSchema, { value: nadaValue.value }), }, }); - case "EcdsaDigestMessage": - return create(ValueSchema, { - value: { - case: "ecdsaMessageDigest", - value: create(EcdsaMessageDigestSchema, { digest: nadaValue.digest }), - }, - }); case "SecretBlob": return create(ValueSchema, { value: { @@ -108,6 +105,13 @@ function nadaValueToProto(nadaValue: EncryptedNadaValueRecord): Value { }), }, }); + case "EcdsaDigestMessage": + return create(ValueSchema, { + value: { + case: "ecdsaMessageDigest", + value: create(EcdsaMessageDigestSchema, { digest: nadaValue.digest }), + }, + }); case "EcdsaSignature": return create(ValueSchema, { value: { @@ -118,6 +122,43 @@ function nadaValueToProto(nadaValue: EncryptedNadaValueRecord): Value { }), }, }); + case "EddsaPublicKey": + return create(ValueSchema, { + value: { + case: "eddsaPublicKey", + value: create(EddsaPublicKeySchema, { + publicKey: nadaValue.publicKey, + }), + }, + }); + case "EddsaPrivateKey": + return create(ValueSchema, { + value: { + case: "eddsaPrivateKeyShare", + value: create(EddsaPrivateKeyShareSchema, { + i: Number.parseInt(nadaValue.i), + x: nadaValue.x, + sharedPublicKey: nadaValue.sharedPublicKey, + publicShares: nadaValue.publicShares, + }), + }, + }); + case "EddsaMessage": + return create(ValueSchema, { + value: { + case: "eddsaMessage", + value: create(EddsaMessageSchema, { message: nadaValue.message }), + }, + }); + case "EddsaSignature": + return create(ValueSchema, { + value: { + case: "eddsaSignature", + value: create(EddsaSignatureSchema, { + signature: nadaValue.signature, + }), + }, + }); case "EcdsaPublicKey": return create(ValueSchema, { value: { @@ -159,8 +200,6 @@ function nadaValueFromProto( return { type: "UnsignedInteger", value: value.value.value.value }; case "publicBoolean": return { type: "Boolean", value: value.value.value.value }; - case "ecdsaMessageDigest": - return { type: "EcdsaDigestMessage", digest: value.value.value.digest }; case "shamirSharesBlob": return { type: "SecretBlob", @@ -176,6 +215,8 @@ function nadaValueFromProto( }; case "shamirShareBoolean": return { type: "ShamirShareBoolean", value: value.value.value.value }; + case "ecdsaMessageDigest": + return { type: "EcdsaDigestMessage", digest: value.value.value.digest }; case "ecdsaPrivateKeyShare": return { type: "EcdsaPrivateKey", @@ -195,6 +236,26 @@ function nadaValueFromProto( type: "EcdsaPublicKey", publicKey: value.value.value.publicKey, }; + case "eddsaMessage": + return { type: "EddsaMessage", message: value.value.value.message }; + case "eddsaPrivateKeyShare": + return { + type: "EddsaPrivateKey", + i: value.value.value.i.toString(), + x: value.value.value.x, + sharedPublicKey: value.value.value.sharedPublicKey, + publicShares: value.value.value.publicShares, + }; + case "eddsaSignature": + return { + type: "EddsaSignature", + signature: value.value.value.signature, + }; + case "eddsaPublicKey": + return { + type: "EddsaPublicKey", + publicKey: value.value.value.publicKey, + }; case "storeId": return { type: "StoreId", diff --git a/client-vms/tests/signature.test.ts b/client-vms/tests/ecdsa.test.ts similarity index 97% rename from client-vms/tests/signature.test.ts rename to client-vms/tests/ecdsa.test.ts index 04a0e2c8..8a10b3f7 100644 --- a/client-vms/tests/signature.test.ts +++ b/client-vms/tests/ecdsa.test.ts @@ -11,7 +11,7 @@ import { import { UpdatePermissionsBuilder, type VmClient, VmClientBuilder } from "#/vm"; import { Env, PrivateKeyPerSuite } from "./helpers"; -describe("Signature", () => { +describe("Ecdsa Signature", () => { // Program id const tecdsaProgramId = "builtin/tecdsa_sign"; // Input store name @@ -31,7 +31,9 @@ describe("Signature", () => { let client: VmClient; beforeAll(async () => { - const signer = await createSignerFromKey(PrivateKeyPerSuite.Signatures); + const signer = await createSignerFromKey( + PrivateKeyPerSuite.EcdsaSignatures, + ); digestMessage = sha256("A deep message with a deep number: 42"); client = await new VmClientBuilder() diff --git a/client-vms/tests/eddsa.test.ts b/client-vms/tests/eddsa.test.ts new file mode 100644 index 00000000..7ddb265c --- /dev/null +++ b/client-vms/tests/eddsa.test.ts @@ -0,0 +1,141 @@ +import { type EddsaSignature, NadaValue } from "@nillion/client-wasm"; +import { ed25519 } from "@noble/curves/ed25519"; +import { sha256 } from "@noble/hashes/sha2"; +import { beforeAll, describe, expect, it } from "vitest"; +import { createSignerFromKey } from "#/payment"; +import { + type NadaValuesRecord, + type Uuid, + ValuesPermissionsBuilder, +} from "#/types"; +import { UpdatePermissionsBuilder, type VmClient, VmClientBuilder } from "#/vm"; +import { Env, PrivateKeyPerSuite } from "./helpers"; + +// This is ignored because NadaValue::new_eddsa_private_key fails for random private keys. This should be fixed +// in nilvm side +describe.skip("Eddsa Signature", () => { + // Program id + const teddsaProgramId = "builtin/teddsa_sign"; + // Input store name + const teddsaKeyName = "teddsa_private_key"; + const teddsaDigestName = "teddsa_digest_message"; + const teddsaSignatureName = "teddsa_signature"; + // Party names + const teddsaKeyParty = "teddsa_key_party"; + const teddsaDigestParty = "teddsa_digest_message_party"; + const teddsaOutputParty = "teddsa_output_party"; + + const privateKey: Uint8Array = ed25519.utils.randomPrivateKey(); + const publicKey: Uint8Array = ed25519.getPublicKey(privateKey); + + let digestMessage: Uint8Array; + + let client: VmClient; + + beforeAll(async () => { + const signer = await createSignerFromKey( + PrivateKeyPerSuite.EddsaSignatures, + ); + digestMessage = sha256("A deep message with a deep number: 42"); + + client = await new VmClientBuilder() + .seed("tests") + .bootnodeUrl(Env.bootnodeUrl) + .chainUrl(Env.nilChainUrl) + .signer(signer) + .build(); + }); + + let privateKeyStoreId: Uuid; + it("store private key", async () => { + privateKeyStoreId = await client + .storeValues() + .ttl(1) + .value(teddsaKeyName, NadaValue.new_eddsa_private_key(privateKey)) + .build() + .invoke(); + expect(privateKeyStoreId).toHaveLength(36); + }); + + it("update private key permissions", async () => { + const permissions = UpdatePermissionsBuilder.init(client) + .valuesId(privateKeyStoreId) + .grantCompute(client.id, teddsaProgramId) + .build(); + await permissions.invoke(); + }); + + it("retrieve private key", async () => { + const data = await client + .retrieveValues() + .id(privateKeyStoreId) + .build() + .invoke(); + + const values = data[teddsaKeyName]!; + expect(values).toBeDefined(); + expect(values.type).toBe("EddsaPrivateKey"); + expect(values.value).toEqual(privateKey); + }); + + let digestMessageStoreId: Uuid; + it("store digest message", async () => { + const permissions = ValuesPermissionsBuilder.defaultOwner(client.id) + .grantCompute(client.id, teddsaProgramId) + .build(); + digestMessageStoreId = await client + .storeValues() + .ttl(1) + .value(teddsaDigestName, NadaValue.new_eddsa_message(digestMessage)) + .permissions(permissions) + .build() + .invoke(); + expect(digestMessageStoreId).toHaveLength(36); + }); + + it("retrieve digest message", async () => { + const data = await client + .retrieveValues() + .id(digestMessageStoreId) + .build() + .invoke(); + + const values = data[teddsaDigestName]!; + expect(values).toBeDefined(); + expect(values.type).toBe("EddsaDigestMessage"); + expect(values.value).toEqual(digestMessage); + }); + + let computeResultId: Uuid; + it("sign message", async () => { + computeResultId = await client + .invokeCompute() + .program(teddsaProgramId) + .inputParty(teddsaKeyParty, client.id) + .inputParty(teddsaDigestParty, client.id) + .outputParty(teddsaOutputParty, [client.id]) + .valueIds(privateKeyStoreId, digestMessageStoreId) + .build() + .invoke(); + expect(computeResultId).toHaveLength(36); + }); + + let computeResult: NadaValuesRecord; + it("retrieve signature", async () => { + computeResult = await client + .retrieveComputeResult() + .id(computeResultId) + .build() + .invoke(); + + const values = computeResult[teddsaSignatureName]!; + expect(values).toBeDefined(); + }); + + it("eddsa verify", async () => { + const signature = computeResult[teddsaSignatureName] + ?.value as EddsaSignature; + expect(ed25519.verify(signature.signature(), digestMessage, publicKey)) + .true; + }); +}); diff --git a/client-vms/tests/helpers.ts b/client-vms/tests/helpers.ts index e09eb8a8..a167e306 100644 --- a/client-vms/tests/helpers.ts +++ b/client-vms/tests/helpers.ts @@ -24,8 +24,8 @@ export const PrivateKeyPerSuite = { Payments: Env.nilChainPrivateKey0, LeaderQuery: Env.nilChainPrivateKey1, VmClient: Env.nilChainPrivateKey2, - Signatures: Env.nilChainPrivateKey3, - // Env.nilChainPrivateKey4, + EcdsaSignatures: Env.nilChainPrivateKey3, + EddsaSignatures: Env.nilChainPrivateKey4, // Env.nilChainPrivateKey5, // Env.nilChainPrivateKey6, // Env.nilChainPrivateKey7, diff --git a/client-vms/tests/wasm.test.ts b/client-vms/tests/wasm.test.ts index 9312455b..306ad25d 100644 --- a/client-vms/tests/wasm.test.ts +++ b/client-vms/tests/wasm.test.ts @@ -1,8 +1,10 @@ import { type EcdsaSignature, + type EddsaSignature, NadaValue, NadaValues, } from "@nillion/client-wasm"; +import { secp256k1 } from "@noble/curves/secp256k1"; import { sha256 } from "@noble/hashes/sha2"; import { describe, expect, it } from "vitest"; import { type NadaValuesRecord, PartyId } from "#/types"; @@ -16,11 +18,18 @@ const numericTypes = [ const booleanTypes = ["SecretBoolean", "PublicBoolean"]; +const ecdsaPrivateKey = secp256k1.utils.randomPrivateKey(); + const byteArray = Uint8Array.from([ 186, 236, 247, 198, 7, 225, 204, 147, 116, 47, 207, 45, 149, 49, 212, 168, 136, 145, 98, 150, 152, 122, 50, 91, 141, 227, 182, 233, 8, 245, 72, 38, ]); +const privateKey = Uint8Array.from([ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, +]); + const pubKey = Uint8Array.from([ 186, 236, 247, 198, 7, 225, 204, 147, 116, 47, 207, 45, 149, 49, 212, 168, 136, 145, 98, 150, 152, 122, 50, 91, 141, 227, 182, 233, 8, 245, 72, 38, 56, @@ -30,6 +39,21 @@ const storeId = Uint8Array.from([ 186, 236, 247, 198, 7, 225, 204, 147, 116, 47, 207, 45, 149, 49, 212, 168, ]); +const eddsaSignatureR = Uint8Array.from([ + 228, 118, 63, 53, 138, 161, 20, 164, 93, 86, 233, 11, 211, 204, 186, 63, 255, + 174, 220, 173, 222, 58, 64, 79, 108, 173, 130, 1, 134, 44, 244, 104, +]); + +const eddsaSignatureZ = Uint8Array.from([ + 137, 73, 233, 168, 34, 64, 148, 185, 177, 91, 184, 21, 246, 82, 65, 207, 83, + 158, 44, 181, 199, 94, 83, 178, 88, 238, 210, 220, 10, 49, 154, 1, +]); + +const eddsaPublicKey = Uint8Array.from([ + 186, 236, 247, 198, 7, 225, 204, 147, 116, 47, 207, 45, 149, 49, 212, 168, + 136, 145, 98, 150, 152, 122, 50, 91, 141, 227, 182, 233, 8, 245, 72, 38, +]); + const digestMessage = "A deep message with a deep number: 42"; const data = [ @@ -78,8 +102,8 @@ const data = [ { type: "EcdsaPrivateKey", name: "h", - value: byteArray, - nadaValue: NadaValue.new_ecdsa_private_key(byteArray), + value: ecdsaPrivateKey, + nadaValue: NadaValue.new_ecdsa_private_key(ecdsaPrivateKey), }, { type: "EcdsaDigestMessage", @@ -105,6 +129,31 @@ const data = [ value: storeId, nadaValue: NadaValue.new_store_id(storeId), }, + { + type: "EddsaPrivateKey", + name: "m", + value: privateKey, + nadaValue: NadaValue.new_eddsa_private_key(privateKey), + }, + { + type: "EddsaMessage", + name: "n", + value: sha256(digestMessage), + nadaValue: NadaValue.new_eddsa_message(sha256(digestMessage)), + }, + { + type: "EddsaSignature", + name: "o", + r: eddsaSignatureR, + z: eddsaSignatureZ, + nadaValue: NadaValue.new_eddsa_signature(eddsaSignatureR, eddsaSignatureZ), + }, + { + type: "EddsaPublicKey", + name: "p", + value: eddsaPublicKey, + nadaValue: NadaValue.new_eddsa_public_key(eddsaPublicKey), + }, ]; describe("Wasm compatability", () => { @@ -129,6 +178,10 @@ describe("Wasm compatability", () => { const signature = actual?.value as EcdsaSignature; expect(signature.r()).toEqual(test.value); expect(signature.s()).toEqual(test.value); + } else if (actual?.type === "EddsaSignature") { + const signature = actual?.value as EddsaSignature; + expect(signature.r()).toEqual(test.r); + expect(signature.z()).toEqual(test.z); } else { if (numericTypes.includes(actual?.type)) { value = Number(actual?.value); diff --git a/client-wasm/Cargo.lock b/client-wasm/Cargo.lock index 61eb01bf..9a875c61 100644 --- a/client-wasm/Cargo.lock +++ b/client-wasm/Cargo.lock @@ -39,12 +39,18 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "basic-types" version = "0.1.0" dependencies = [ "hex", - "thiserror", + "thiserror 1.0.69", "uuid", ] @@ -102,6 +108,37 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cggmp21-keygen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaa8c850290c494f951abe0350e56c31e4f5664863490197490ff48cb825447d" +dependencies = [ + "digest", + "displaydoc", + "generic-ec", + "generic-ec-zkp", + "hex", + "key-share", + "rand_core", + "round-based", + "serde", + "serde_with", + "sha2", + "thiserror 1.0.69", + "udigest", +] + +[[package]] +name = "chrono" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +dependencies = [ + "num-traits", + "serde", +] + [[package]] name = "client-wasm" version = "0.3.1" @@ -182,6 +219,8 @@ dependencies = [ "cpufeatures", "curve25519-dalek-derive", "fiat-crypto", + "group", + "rand_core", "rustc_version", "subtle", "zeroize", @@ -198,6 +237,41 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.96", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.96", +] + [[package]] name = "der" version = "0.7.9" @@ -208,6 +282,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "digest" version = "0.10.7" @@ -216,6 +299,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", + "subtle", ] [[package]] @@ -239,17 +323,6 @@ dependencies = [ "proc-macro-error", ] -[[package]] -name = "ecdsa-keypair" -version = "0.1.0" -dependencies = [ - "generic-ec", - "key-share", - "rand", - "subtle", - "thiserror", -] - [[package]] name = "educe" version = "0.4.23" @@ -367,12 +440,50 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + [[package]] name = "generic-array" version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ + "serde", "typenum", "version_check", "zeroize", @@ -385,12 +496,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de1099ac0b4d87261d67ff5d4ed400af617a1da40b58908d759b9cf5fd8ed27" dependencies = [ "curve25519-dalek", + "digest", "generic-ec-core", "generic-ec-curves", "hex", - "phantom-type", + "phantom-type 0.4.2", "rand_core", + "rand_hash", + "serde", + "serde_with", "subtle", + "udigest", "zeroize", ] @@ -402,6 +518,7 @@ checksum = "dcba5fdf70cc3ce5805c487f8523b4ceeb32e8ec5237c71ffd93c1ca47a97fee" dependencies = [ "generic-array", "rand_core", + "serde", "subtle", "zeroize", ] @@ -412,8 +529,10 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7c6d23001a5eb60eec2b785a63d2ca965fdfbaf3314b3b46df047398369e28" dependencies = [ + "curve25519-dalek", "elliptic-curve", "generic-ec-core", + "group", "k256", "rand_core", "sha2", @@ -448,6 +567,24 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "givre" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af482004b1f70b5b3b584c3fc3733dd24c71f8c0081a6087f49e09746746788a" +dependencies = [ + "cggmp21-keygen", + "digest", + "generic-ec", + "hd-wallet", + "k256", + "key-share", + "rand_core", + "serde", + "sha2", + "static_assertions", +] + [[package]] name = "group" version = "0.13.0" @@ -465,6 +602,19 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +[[package]] +name = "hd-wallet" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6522551bb35937363845f39a6d4c49e60bdb35a8f7154ebdd078cab50be97992" +dependencies = [ + "generic-array", + "generic-ec", + "hmac", + "sha2", + "subtle", +] + [[package]] name = "heck" version = "0.4.1" @@ -482,6 +632,24 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "indexmap" @@ -503,6 +671,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + [[package]] name = "jit-compiler" version = "0.1.0" @@ -516,7 +690,7 @@ dependencies = [ "nada-compiler-backend", "nada-type", "substring", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -541,14 +715,18 @@ dependencies = [ [[package]] name = "key-share" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10fce16fa05b2c8e6e36096506ef4a98d410159991ccfeb38a7eeb5f296588f6" +checksum = "3ee8e510bb9f738ac400b7dedd98aeb23677c6b48cd3b1b682651ea5091f4282" dependencies = [ "displaydoc", "generic-ec", "generic-ec-zkp", + "hex", "rand_core", + "serde", + "serde_with", + "thiserror 1.0.69", ] [[package]] @@ -573,14 +751,13 @@ checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" name = "math_lib" version = "0.1.0" dependencies = [ - "basic-types", "crypto-bigint", "num-bigint", "num-traits", "paste", "rand", "subtle", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -610,7 +787,7 @@ dependencies = [ "serde", "serde_repr", "substring", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -628,12 +805,12 @@ name = "mpc-vm" version = "0.1.0" dependencies = [ "anyhow", - "ecdsa-keypair", "generic-ec", "jit-compiler", "nada-compiler-backend", "nada-value", "strum", + "threshold-keypair", ] [[package]] @@ -648,12 +825,11 @@ version = "0.1.0" dependencies = [ "anyhow", "ariadne", - "basic-types", "duplicate", "mir-model", "nada-value", "num-bigint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -665,7 +841,7 @@ dependencies = [ "serde", "strum", "strum_macros", - "thiserror", + "thiserror 1.0.69", "types-proc-macros", ] @@ -675,9 +851,9 @@ version = "0.1.0" dependencies = [ "anyhow", "basic-types", - "ecdsa-keypair", "enum-as-inner", "generic-ec", + "givre", "indexmap", "key-share", "math_lib", @@ -686,7 +862,8 @@ dependencies = [ "num-traits", "shamir-sharing", "strum_macros", - "thiserror", + "thiserror 1.0.69", + "threshold-keypair", "types-proc-macros", ] @@ -695,13 +872,13 @@ name = "nillion-client-core" version = "0.1.0" dependencies = [ "basic-types", - "ecdsa-keypair", "key-share", "math_lib", "mpc-vm", "nada-value", "program-auditor", "shamir-sharing", + "threshold-keypair", ] [[package]] @@ -714,6 +891,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" version = "0.1.46" @@ -754,6 +937,15 @@ dependencies = [ "indexmap", ] +[[package]] +name = "phantom-type" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f710afd11c9711b04f97ab61bb9747d5a04562fdf0f9f44abc3de92490084982" +dependencies = [ + "educe", +] + [[package]] name = "phantom-type" version = "0.4.2" @@ -763,6 +955,24 @@ dependencies = [ "educe", ] +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -822,7 +1032,7 @@ dependencies = [ "anyhow", "mpc-vm", "nada-compiler-backend", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -925,6 +1135,17 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16bc1dd921383c6564eb0b8252f5b3f6622b84d40c6e35f5e6790e1fd7abb7a9" +dependencies = [ + "digest", + "rand_core", + "udigest", +] + [[package]] name = "regex" version = "1.11.1" @@ -954,6 +1175,30 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "round-based" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da76edf50de0a9d6911fc79261bb04cc9f3f3a375e0201799f5edf58499af341" +dependencies = [ + "futures-util", + "phantom-type 0.3.1", + "round-based-derive", + "thiserror 2.0.11", + "tracing", +] + +[[package]] +name = "round-based-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afa4d5b318bcafae8a7ebc57c1cb7d4b2db7358293e34d71bfd605fd327cc13" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "rustc-hash" version = "2.1.0" @@ -988,6 +1233,12 @@ version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +[[package]] +name = "ryu" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" + [[package]] name = "same-file" version = "1.0.6" @@ -1047,6 +1298,18 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "serde_json" +version = "1.0.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + [[package]] name = "serde_repr" version = "0.1.19" @@ -1058,6 +1321,33 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +dependencies = [ + "base64", + "chrono", + "hex", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.96", +] + [[package]] name = "sha2" version = "0.10.8" @@ -1078,7 +1368,7 @@ dependencies = [ "math_lib", "rand", "rustc-hash", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1087,6 +1377,18 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "strum" version = "0.26.3" @@ -1166,7 +1468,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl 2.0.11", ] [[package]] @@ -1180,6 +1491,64 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "thiserror-impl" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "threshold-keypair" +version = "0.1.0" +dependencies = [ + "generic-ec", + "givre", + "key-share", + "rand", + "subtle", + "thiserror 1.0.69", +] + +[[package]] +name = "time" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" + [[package]] name = "typenum" version = "1.17.0" @@ -1202,6 +1571,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cd61fa9fb78569e9fe34acf0048fd8cb9ebdbacc47af740745487287043ff0" dependencies = [ + "digest", "udigest-derive", ] diff --git a/client-wasm/dist/index.d.ts b/client-wasm/dist/index.d.ts index 369d891b..598b9c80 100644 --- a/client-wasm/dist/index.d.ts +++ b/client-wasm/dist/index.d.ts @@ -26,6 +26,36 @@ export class EcdsaSignature { */ s(): Uint8Array; } +/** + * A eddsa signature + */ +export class EddsaSignature { +/** +** Return copy of self without private attributes. +*/ + toJSON(): Object; +/** +* Return stringified version of self. +*/ + toString(): string; + free(): void; + /** + * Construct a new instance the components. + */ + constructor(r: Uint8Array, z: Uint8Array); + /** + * Access r component of the signature + */ + r(): Uint8Array; + /** + * Access z component of the signature + */ + z(): Uint8Array; + /** + * Access value of the signature + */ + signature(): Uint8Array; +} export class EncodedModulo { private constructor(); free(): void; @@ -176,6 +206,47 @@ export class NadaValue { * const value = NadaValue::new_ecdsa_public_key([0, 12, ..., 12]); */ static new_ecdsa_public_key(value: Uint8Array): NadaValue; + /** + * Create a new eddsa private key + * + * @param {Uint8Array} value - The ecdsa private key in binary (byte array) encoded format + * @return {NadaValue} The encoded secret corresponding to the value provided + * + * @example + * const value = NadaValue.new_eddsa_private_key([1,0,1,222,21,...]); + */ + static new_eddsa_private_key(value: Uint8Array): NadaValue; + /** + * Create a new eddsa message. + * + * @param {Uint8Array} value - The eddsa digest message in binary (byte array) encoded format + * @return {NadaValue} The encoded secret corresponding to the value provided + * + * @example + * const value = NadaValue.new_eddsa_message([1,0,1,222,21,...]); + */ + static new_eddsa_message(value: Uint8Array): NadaValue; + /** + * Create a new eddsa signature. + * + * @param {Uint8Array} r - The r component of the signature in binary (byte array) encoded format + * @param {Uint8Array} z - The z component of the signature in binary (byte array) encoded format + * @return {NadaValue} The encoded secret corresponding to the value provided + * + * @example + * const value = NadaValue::new_eddsa_signature(EddsaSignature { r, z }); + */ + static new_eddsa_signature(r: Uint8Array, z: Uint8Array): NadaValue; + /** + * Create a new eddsa public key. + * + * @param {Uint8Array} value - The value component of the public key in binary (byte array) encoded format + * @return {NadaValue} The encoded secret corresponding to the value provided + * + * @example + * const value = NadaValue::new_eddsa_public_key([0, 12, ..., 12]); + */ + static new_eddsa_public_key(value: Uint8Array): NadaValue; /** * Create a store id. * @@ -203,13 +274,25 @@ export class NadaValue { * * This is only valid for EcdsaSignature. * @return {Uint8Array} the byte array contained in this value. - * @throws {Error} if the value is not a secret blob. + * @throws {Error} if the value is not a ecdsa signature * * @example * const value = NadaValue.new_ecdsa_signature([1,0,1,222,21], [1,0,1,222,21]); * const signature = value.to_ecdsa_signature(); */ to_ecdsa_signature(): EcdsaSignature; + /** + * Convert this NadaValue into an EddsaSignature. + * + * This is only valid for EddsaSignature. + * @return {Uint8Array} the byte array contained in this value. + * @throws {Error} if the value is not a eddsa signature + * + * @example + * const value = NadaValue.new_eddsa_signature([1,0,1,222,21], [1,0,1,222,21]); + * const signature = value.to_eddsa_signature(); + */ + to_eddsa_signature(): EddsaSignature; /** * Convert this value into a string representation of the underlying numeric value. * diff --git a/client-wasm/dist/index_bg.js b/client-wasm/dist/index_bg.js index 3abfed1c..6ed1face 100644 --- a/client-wasm/dist/index_bg.js +++ b/client-wasm/dist/index_bg.js @@ -312,6 +312,83 @@ export class EcdsaSignature { } } +const EddsaSignatureFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_eddsasignature_free(ptr >>> 0, 1)); +/** + * A eddsa signature + */ +export class EddsaSignature { + + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(EddsaSignature.prototype); + obj.__wbg_ptr = ptr; + EddsaSignatureFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + + toJSON() { + return { + }; + } + + toString() { + return JSON.stringify(this); + } + + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + EddsaSignatureFinalization.unregister(this); + return ptr; + } + + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_eddsasignature_free(ptr, 0); + } + /** + * Construct a new instance the components. + * @param {Uint8Array} r + * @param {Uint8Array} z + */ + constructor(r, z) { + const ptr0 = passArray8ToWasm0(r, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(z, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.ecdsasignature_new(ptr0, len0, ptr1, len1); + this.__wbg_ptr = ret >>> 0; + EddsaSignatureFinalization.register(this, this.__wbg_ptr, this); + return this; + } + /** + * Access r component of the signature + * @returns {Uint8Array} + */ + r() { + const ret = wasm.ecdsasignature_r(this.__wbg_ptr); + return takeObject(ret); + } + /** + * Access z component of the signature + * @returns {Uint8Array} + */ + z() { + const ret = wasm.ecdsasignature_s(this.__wbg_ptr); + return takeObject(ret); + } + /** + * Access value of the signature + * @returns {Uint8Array} + */ + signature() { + const ret = wasm.eddsasignature_signature(this.__wbg_ptr); + return takeObject(ret); + } +} + const EncodedModuloFinalization = (typeof FinalizationRegistry === 'undefined') ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry(ptr => wasm.__wbg_encodedmodulo_free(ptr >>> 0, 1)); @@ -727,6 +804,113 @@ export class NadaValue { wasm.__wbindgen_add_to_stack_pointer(16); } } + /** + * Create a new eddsa private key + * + * @param {Uint8Array} value - The ecdsa private key in binary (byte array) encoded format + * @return {NadaValue} The encoded secret corresponding to the value provided + * + * @example + * const value = NadaValue.new_eddsa_private_key([1,0,1,222,21,...]); + */ + static new_eddsa_private_key(value) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(value, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + wasm.nadavalue_new_eddsa_private_key(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return NadaValue.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create a new eddsa message. + * + * @param {Uint8Array} value - The eddsa digest message in binary (byte array) encoded format + * @return {NadaValue} The encoded secret corresponding to the value provided + * + * @example + * const value = NadaValue.new_eddsa_message([1,0,1,222,21,...]); + */ + static new_eddsa_message(value) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(value, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + wasm.nadavalue_new_eddsa_message(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return NadaValue.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create a new eddsa signature. + * + * @param {Uint8Array} r - The r component of the signature in binary (byte array) encoded format + * @param {Uint8Array} z - The z component of the signature in binary (byte array) encoded format + * @return {NadaValue} The encoded secret corresponding to the value provided + * + * @example + * const value = NadaValue::new_eddsa_signature(EddsaSignature { r, z }); + */ + static new_eddsa_signature(r, z) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(r, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(z, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + wasm.nadavalue_new_eddsa_signature(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return NadaValue.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create a new eddsa public key. + * + * @param {Uint8Array} value - The value component of the public key in binary (byte array) encoded format + * @return {NadaValue} The encoded secret corresponding to the value provided + * + * @example + * const value = NadaValue::new_eddsa_public_key([0, 12, ..., 12]); + */ + static new_eddsa_public_key(value) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(value, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + wasm.nadavalue_new_eddsa_public_key(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return NadaValue.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } /** * Create a store id. * @@ -787,7 +971,7 @@ export class NadaValue { * * This is only valid for EcdsaSignature. * @return {Uint8Array} the byte array contained in this value. - * @throws {Error} if the value is not a secret blob. + * @throws {Error} if the value is not a ecdsa signature * * @example * const value = NadaValue.new_ecdsa_signature([1,0,1,222,21], [1,0,1,222,21]); @@ -808,6 +992,32 @@ export class NadaValue { wasm.__wbindgen_add_to_stack_pointer(16); } } + /** + * Convert this NadaValue into an EddsaSignature. + * + * This is only valid for EddsaSignature. + * @return {Uint8Array} the byte array contained in this value. + * @throws {Error} if the value is not a eddsa signature + * + * @example + * const value = NadaValue.new_eddsa_signature([1,0,1,222,21], [1,0,1,222,21]); + * const signature = value.to_eddsa_signature(); + */ + to_eddsa_signature() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.nadavalue_to_eddsa_signature(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return EddsaSignature.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } /** * Convert this value into a string representation of the underlying numeric value. * @@ -1517,6 +1727,11 @@ export function __wbg_ecdsasignature_new(arg0) { return addHeapObject(ret); }; +export function __wbg_eddsasignature_new(arg0) { + const ret = EddsaSignature.__wrap(arg0); + return addHeapObject(ret); +}; + export function __wbg_from_2a5d3e218e67aa85(arg0) { const ret = Array.from(getObject(arg0)); return addHeapObject(ret); diff --git a/client-wasm/dist/index_bg.wasm b/client-wasm/dist/index_bg.wasm index cf0bcb56..f92a7083 100644 Binary files a/client-wasm/dist/index_bg.wasm and b/client-wasm/dist/index_bg.wasm differ diff --git a/client-wasm/dist/index_bg.wasm.d.ts b/client-wasm/dist/index_bg.wasm.d.ts index d2ac9382..49b4cd97 100644 --- a/client-wasm/dist/index_bg.wasm.d.ts +++ b/client-wasm/dist/index_bg.wasm.d.ts @@ -13,9 +13,14 @@ export const nadavalue_new_ecdsa_private_key: (a: number, b: number, c: number) export const nadavalue_new_ecdsa_digest_message: (a: number, b: number, c: number) => void; export const nadavalue_new_ecdsa_signature: (a: number, b: number, c: number, d: number, e: number) => void; export const nadavalue_new_ecdsa_public_key: (a: number, b: number, c: number) => void; +export const nadavalue_new_eddsa_private_key: (a: number, b: number, c: number) => void; +export const nadavalue_new_eddsa_message: (a: number, b: number, c: number) => void; +export const nadavalue_new_eddsa_signature: (a: number, b: number, c: number, d: number, e: number) => void; +export const nadavalue_new_eddsa_public_key: (a: number, b: number, c: number) => void; export const nadavalue_new_store_id: (a: number, b: number, c: number) => void; export const nadavalue_to_byte_array: (a: number, b: number) => void; export const nadavalue_to_ecdsa_signature: (a: number, b: number) => void; +export const nadavalue_to_eddsa_signature: (a: number, b: number) => void; export const nadavalue_to_integer: (a: number, b: number) => void; export const nadavalue_type_name: (a: number, b: number) => void; export const __wbg_nadavalues_free: (a: number, b: number) => void; @@ -27,6 +32,7 @@ export const __wbg_ecdsasignature_free: (a: number, b: number) => void; export const ecdsasignature_new: (a: number, b: number, c: number, d: number) => number; export const ecdsasignature_r: (a: number) => number; export const ecdsasignature_s: (a: number) => number; +export const eddsasignature_signature: (a: number) => number; export const __wbg_partyid_free: (a: number, b: number) => void; export const partyid_new: (a: number, b: number) => number; export const partyid_to_byte_array: (a: number) => number; @@ -55,6 +61,10 @@ export const partyshares_shares: (a: number) => number; export const __wbg_encryptednadavalues_free: (a: number, b: number) => void; export const encryptednadavalues_to_js_object: (a: number, b: number) => void; export const encryptednadavalues_from_js_object: (a: number, b: number, c: number) => void; +export const eddsasignature_new: (a: number, b: number, c: number, d: number) => number; +export const eddsasignature_z: (a: number) => number; +export const eddsasignature_r: (a: number) => number; +export const __wbg_eddsasignature_free: (a: number, b: number) => void; export const __wbg_programmetadata_free: (a: number, b: number) => void; export const programmetadata_new: (a: number, b: number, c: number) => void; export const programmetadata_memory_size: (a: number) => bigint; diff --git a/client-wasm/src/values.rs b/client-wasm/src/values.rs index bd2edebe..ce193743 100644 --- a/client-wasm/src/values.rs +++ b/client-wasm/src/values.rs @@ -2,9 +2,9 @@ use crate::errors::{JsResult, ValueError}; use js_sys::{Array, Object, Uint8Array}; use nillion_client_core::{ - generic_ec::{curves::Secp256k1, serde::CurveName, NonZero, Point, Scalar, SecretScalar}, + generic_ec::{curves::Secp256k1, serde::CurveName, Curve, NonZero, Point, Scalar, SecretScalar}, key_share::{DirtyCoreKeyShare, DirtyKeyInfo, Validate}, - privatekey::{EcdsaPrivateKey, EcdsaPrivateKeyShare}, + privatekey::{ThresholdPrivateKey, ThresholdPrivateKeyShare}, publickey::EcdsaPublicKeyArray, signature, signature::EcdsaSignatureShare, @@ -132,7 +132,7 @@ impl NadaValue { /// const value = NadaValue.new_ecdsa_private_key([1,0,1,222,21,...]); #[wasm_bindgen(skip_jsdoc)] pub fn new_ecdsa_private_key(value: Vec) -> JsResult { - let private_key = EcdsaPrivateKey::from_bytes(&value) + let private_key = ThresholdPrivateKey::from_be_bytes(&value) .map_err(|e| ValueError::new_err(&format!("Invalid ecdsa private key: {e}")))?; let secret = nillion_client_core::values::NadaValue::new_ecdsa_private_key(private_key); Ok(Self(secret)) @@ -182,6 +182,62 @@ impl NadaValue { Ok(Self(nillion_client_core::values::NadaValue::new_ecdsa_public_key::(array.into()))) } + /// Create a new eddsa private key + /// + /// @param {Uint8Array} value - The ecdsa private key in binary (byte array) encoded format + /// @return {NadaValue} The encoded secret corresponding to the value provided + /// + /// @example + /// const value = NadaValue.new_eddsa_private_key([1,0,1,222,21,...]); + #[wasm_bindgen(skip_jsdoc)] + pub fn new_eddsa_private_key(value: Vec) -> JsResult { + let private_key = ThresholdPrivateKey::from_le_bytes(&value) + .map_err(|e| ValueError::new_err(&format!("Invalid eddsa private key: {e}")))?; + let secret = nillion_client_core::values::NadaValue::new_eddsa_private_key(private_key); + Ok(Self(secret)) + } + + /// Create a new eddsa message. + /// + /// @param {Uint8Array} value - The eddsa digest message in binary (byte array) encoded format + /// @return {NadaValue} The encoded secret corresponding to the value provided + /// + /// @example + /// const value = NadaValue.new_eddsa_message([1,0,1,222,21,...]); + #[wasm_bindgen(skip_jsdoc)] + pub fn new_eddsa_message(value: Vec) -> JsResult { + Ok(Self(nillion_client_core::values::NadaValue::new_eddsa_message(value))) + } + + /// Create a new eddsa signature. + /// + /// @param {Uint8Array} r - The r component of the signature in binary (byte array) encoded format + /// @param {Uint8Array} z - The z component of the signature in binary (byte array) encoded format + /// @return {NadaValue} The encoded secret corresponding to the value provided + /// + /// @example + /// const value = NadaValue::new_eddsa_signature(EddsaSignature { r, z }); + #[wasm_bindgen(skip_jsdoc)] + pub fn new_eddsa_signature(r: Vec, z: Vec) -> JsResult { + let signature = signature::EddsaSignature::from_components_bytes(&r, &z) + .map_err(|e| ValueError::new_err(&format!("Invalid eddsa signature: {e}")))?; + Ok(Self(nillion_client_core::values::NadaValue::new_eddsa_signature(signature))) + } + + /// Create a new eddsa public key. + /// + /// @param {Uint8Array} value - The value component of the public key in binary (byte array) encoded format + /// @return {NadaValue} The encoded secret corresponding to the value provided + /// + /// @example + /// const value = NadaValue::new_eddsa_public_key([0, 12, ..., 12]); + #[wasm_bindgen(skip_jsdoc)] + pub fn new_eddsa_public_key(value: Vec) -> JsResult { + let array: [u8; 32] = + value.try_into().map_err(|_| ValueError::new_err("Public key must be exactly 32 bytes long"))?; + Ok(Self(nillion_client_core::values::NadaValue::new_eddsa_public_key(array))) + } + /// Create a store id. /// /// @param {Uint8Array} value - The value component of the store id in binary (byte array) encoded format @@ -208,10 +264,13 @@ impl NadaValue { #[wasm_bindgen(skip_jsdoc)] pub fn to_byte_array(&self) -> Result, JsError> { match &self.0 { - nillion_client_core::values::NadaValue::SecretBlob(value) => Ok(value.to_vec()), - nillion_client_core::values::NadaValue::EcdsaPrivateKey(value) => Ok(value.clone().to_bytes()), - nillion_client_core::values::NadaValue::EcdsaDigestMessage(value) => Ok(value.into()), - nillion_client_core::values::NadaValue::EcdsaPublicKey(public_key) => Ok(public_key.0.into()), + nillion_client_core::values::NadaValue::SecretBlob(v) => Ok(v.to_vec()), + nillion_client_core::values::NadaValue::EcdsaPrivateKey(v) => Ok(v.clone().to_be_bytes()), + nillion_client_core::values::NadaValue::EcdsaDigestMessage(v) => Ok(v.into()), + nillion_client_core::values::NadaValue::EcdsaPublicKey(v) => Ok(v.0.into()), + nillion_client_core::values::NadaValue::EddsaPrivateKey(v) => Ok(v.clone().to_le_bytes()), + nillion_client_core::values::NadaValue::EddsaPublicKey(v) => Ok(v.into()), + nillion_client_core::values::NadaValue::EddsaMessage(v) => Ok(v.to_vec()), nillion_client_core::values::NadaValue::StoreId(store_id) => Ok(store_id.into()), _ => Err(JsError::new("value does not contain a byte array")), } @@ -221,7 +280,7 @@ impl NadaValue { /// /// This is only valid for EcdsaSignature. /// @return {Uint8Array} the byte array contained in this value. - /// @throws {Error} if the value is not a secret blob. + /// @throws {Error} if the value is not a ecdsa signature /// /// @example /// const value = NadaValue.new_ecdsa_signature([1,0,1,222,21], [1,0,1,222,21]); @@ -238,6 +297,26 @@ impl NadaValue { } } + /// Convert this NadaValue into an EddsaSignature. + /// + /// This is only valid for EddsaSignature. + /// @return {Uint8Array} the byte array contained in this value. + /// @throws {Error} if the value is not a eddsa signature + /// + /// @example + /// const value = NadaValue.new_eddsa_signature([1,0,1,222,21], [1,0,1,222,21]); + /// const signature = value.to_eddsa_signature(); + #[wasm_bindgen(skip_jsdoc)] + pub fn to_eddsa_signature(&self) -> Result { + if let nillion_client_core::values::NadaValue::EddsaSignature(signature) = &self.0 { + let r = signature.signature.r.to_bytes().as_bytes().to_vec(); + let z = signature.signature.z.to_le_bytes().to_vec(); + Ok(EddsaSignature::new(r, z)) + } else { + Err(JsError::new("value is not a eddsa signature")) + } + } + /// Convert this value into a string representation of the underlying numeric value. /// /// This only works for numeric secret values, such as integers and unsigned integers. @@ -278,6 +357,10 @@ impl NadaValue { EcdsaDigestMessage(_) => "EcdsaDigestMessage", EcdsaSignature(_) => "EcdsaSignature", EcdsaPublicKey(_) => "EcdsaPublicKey", + EddsaPrivateKey(_) => "EddsaPrivateKey", + EddsaMessage(_) => "EddsaMessage", + EddsaSignature(_) => "EddsaSignature", + EddsaPublicKey(_) => "EddsaPublicKey", StoreId(_) => "StoreId", _ => Err(JsError::new(&format!("Unsupported type {:?}", self.0)))?, }; @@ -353,6 +436,9 @@ impl NadaValues { | nillion_client_core::values::NadaValue::EcdsaPrivateKey(_) | nillion_client_core::values::NadaValue::EcdsaDigestMessage(_) | nillion_client_core::values::NadaValue::EcdsaPublicKey(_) + | nillion_client_core::values::NadaValue::EddsaPrivateKey(_) + | nillion_client_core::values::NadaValue::EddsaMessage(_) + | nillion_client_core::values::NadaValue::EddsaPublicKey(_) | nillion_client_core::values::NadaValue::StoreId(_) => { let byte_array = wrapped.to_byte_array()?; let uint8_array = to_byte_array(&byte_array); @@ -361,6 +447,9 @@ impl NadaValues { nillion_client_core::values::NadaValue::EcdsaSignature(_) => { JsValue::from(wrapped.to_ecdsa_signature()?) } + nillion_client_core::values::NadaValue::EddsaSignature(_) => { + JsValue::from(wrapped.to_eddsa_signature()?) + } _ => JsValue::from(wrapped.to_integer()?), }; @@ -403,6 +492,42 @@ impl EcdsaSignature { } } +/// A eddsa signature +#[wasm_bindgen(inspectable)] +#[derive(Clone)] +pub struct EddsaSignature { + /// r component of the signature in binary format + r: Vec, + /// z component of the signature in binary format + z: Vec, +} + +#[wasm_bindgen] +impl EddsaSignature { + /// Construct a new instance the components. + #[wasm_bindgen(constructor)] + pub fn new(r: Vec, z: Vec) -> Self { + Self { r, z } + } + + /// Access r component of the signature + pub fn r(&self) -> Uint8Array { + to_byte_array(&self.r) + } + + /// Access z component of the signature + pub fn z(&self) -> Uint8Array { + to_byte_array(&self.z) + } + + /// Access value of the signature + pub fn signature(&self) -> Uint8Array { + let mut signature = self.r.clone(); + signature.append(&mut self.z.clone()); + to_byte_array(&signature) + } +} + /// A party identifier. #[wasm_bindgen(inspectable)] #[derive(Clone)] @@ -602,32 +727,7 @@ impl EncryptedNadaValues { .map_err(|_| JsError::new("Failed to set originalSize"))?; } CoreNadaValue::EcdsaPrivateKey(value) => { - let value = value.as_inner(); - // i - js_sys::Reflect::set(&inner_obj, &JsValue::from("i"), &JsValue::from(value.i.to_string())) - .map_err(|_| JsError::new("Failed to set i"))?; - // x - let x = value.x.clone().into_inner().as_ref().to_le_bytes(); - let js_x = JsValue::from(to_byte_array(&x)); - js_sys::Reflect::set(&inner_obj, &JsValue::from("x"), &js_x) - .map_err(|_| JsError::new("Failed to set x"))?; - // shared_public_key - let shared_public_key = value.key_info.shared_public_key.to_bytes(true).to_vec(); - let js_shared_public_key = JsValue::from(to_byte_array(&shared_public_key)); - js_sys::Reflect::set(&inner_obj, &JsValue::from("sharedPublicKey"), &js_shared_public_key) - .map_err(|_| JsError::new("Failed to set sharedPublicKey"))?; - // public_shares - let js_public_shares = value - .key_info - .public_shares - .iter() - .map(|s| { - let share = s.to_bytes(true).to_vec(); - JsValue::from(to_byte_array(&share)) - }) - .collect::(); - js_sys::Reflect::set(&inner_obj, &JsValue::from("publicShares"), &js_public_shares) - .map_err(|_| JsError::new("Failed to set publicShares"))?; + Self::private_key_to_json(&inner_obj, value)?; } CoreNadaValue::EcdsaDigestMessage(value) => { let js_value = JsValue::from(to_byte_array(value)); @@ -645,8 +745,27 @@ impl EncryptedNadaValues { js_sys::Reflect::set(&inner_obj, &JsValue::from("sigma"), &js_sigma) .map_err(|_| JsError::new("Failed to set sigma"))?; } - CoreNadaValue::EcdsaPublicKey(public_key) => { - let js_public_key = JsValue::from(to_byte_array(&public_key.0)); + CoreNadaValue::EcdsaPublicKey(value) => { + let js_public_key = JsValue::from(to_byte_array(&value.0)); + js_sys::Reflect::set(&inner_obj, &JsValue::from("publicKey"), &js_public_key) + .map_err(|_| JsError::new("Failed to set publicKey"))?; + } + CoreNadaValue::EddsaPrivateKey(value) => { + Self::private_key_to_json(&inner_obj, value)?; + } + CoreNadaValue::EddsaMessage(value) => { + let js_value = JsValue::from(to_byte_array(value)); + js_sys::Reflect::set(&inner_obj, &JsValue::from("message"), &js_value) + .map_err(|_| JsError::new("Failed to set message"))?; + } + CoreNadaValue::EddsaSignature(value) => { + let signature = value.to_bytes(); + let js_signature = JsValue::from(to_byte_array(&signature)); + js_sys::Reflect::set(&inner_obj, &JsValue::from("signature"), &js_signature) + .map_err(|_| JsError::new("Failed to set signature"))?; + } + CoreNadaValue::EddsaPublicKey(value) => { + let js_public_key = JsValue::from(to_byte_array(value)); js_sys::Reflect::set(&inner_obj, &JsValue::from("publicKey"), &js_public_key) .map_err(|_| JsError::new("Failed to set publicKey"))?; } @@ -672,6 +791,35 @@ impl EncryptedNadaValues { Ok(JsValue::from(js_obj)) } + fn private_key_to_json(obj: &Object, private_key: &ThresholdPrivateKeyShare) -> JsResult<()> { + let private_key = private_key.as_inner(); + // i + js_sys::Reflect::set(obj, &JsValue::from("i"), &JsValue::from(private_key.i.to_string())) + .map_err(|_| JsError::new("Failed to set i"))?; + // x + let x = private_key.x.clone().into_inner().as_ref().to_le_bytes(); + let js_x = JsValue::from(to_byte_array(&x)); + js_sys::Reflect::set(obj, &JsValue::from("x"), &js_x).map_err(|_| JsError::new("Failed to set x"))?; + // shared_public_key + let shared_public_key = private_key.key_info.shared_public_key.to_bytes(true).to_vec(); + let js_shared_public_key = JsValue::from(to_byte_array(&shared_public_key)); + js_sys::Reflect::set(obj, &JsValue::from("sharedPublicKey"), &js_shared_public_key) + .map_err(|_| JsError::new("Failed to set sharedPublicKey"))?; + // public_shares + let js_public_shares = private_key + .key_info + .public_shares + .iter() + .map(|s| { + let share = s.to_bytes(true).to_vec(); + JsValue::from(to_byte_array(&share)) + }) + .collect::(); + js_sys::Reflect::set(obj, &JsValue::from("publicShares"), &js_public_shares) + .map_err(|_| JsError::new("Failed to set publicShares"))?; + Ok(()) + } + /// Convert a JS object into a EncryptedNadaValues #[wasm_bindgen] pub fn from_js_object(js_object: &JsValue, modulo: EncodedModulo) -> JsResult { @@ -759,38 +907,7 @@ impl EncryptedNadaValues { .map_err(|_| JsError::new("Invalid blob original size"))?; CoreNadaValue::new_secret_blob(BlobPrimitiveType { value: shares, unencoded_size }) } - "EcdsaPrivateKey" => { - // i - let js_i = js_sys::Reflect::get(&value, &JsValue::from("i")) - .map_err(|_| JsError::new("Failed i not found"))? - .as_string() - .unwrap_or_default(); - let i = u16::from_str(&js_i).map_err(|_| JsError::new("Invalid Ecdsa i"))?; - // x - let js_x = js_sys::Reflect::get(&value, &JsValue::from("x")) - .map_err(|_| JsError::new("Failed x not found"))?; - let x = non_zero_secret_scalar_from_js_value(js_x)?; - // key_info - let js_shared_public_key = js_sys::Reflect::get(&value, &JsValue::from("sharedPublicKey")) - .map_err(|_| JsError::new("Failed sharedPublicKey not found"))?; - let js_public_shares = js_sys::Reflect::get(&value, &JsValue::from("publicShares")) - .map_err(|_| JsError::new("Failed publicShares not found"))?; - let key_info = DirtyKeyInfo { - curve: CurveName::new(), - shared_public_key: non_zero_point_from_js_value(js_shared_public_key)?, - public_shares: Array::from(&js_public_shares) - .to_vec() - .into_iter() - .map(non_zero_point_from_js_value) - .collect::>()?, - vss_setup: None, - }; - - let share = DirtyCoreKeyShare { i, key_info, x } - .validate() - .map_err(|e| JsError::new(&format!("invalid ecdsa private key: {e:?}")))?; - CoreNadaValue::new_ecdsa_private_key(EcdsaPrivateKeyShare::new(share)) - } + "EcdsaPrivateKey" => CoreNadaValue::new_ecdsa_private_key(Self::json_to_private_key(&value)?), "EcdsaDigestMessage" => { let js_digest = js_sys::Reflect::get(&value, &JsValue::from("digest")) .map_err(|_| JsError::new("Failed digest not found"))?; @@ -824,6 +941,30 @@ impl EncryptedNadaValues { .map_err(|_| JsError::new("ecdsa public key must be 33 bytes"))?; CoreNadaValue::new_ecdsa_public_key::(public_key.into()) } + "EddsaPrivateKey" => CoreNadaValue::new_eddsa_private_key(Self::json_to_private_key(&value)?), + "EddsaMessage" => { + let js_message = js_sys::Reflect::get(&value, &JsValue::from("message")) + .map_err(|_| JsError::new("Failed eddsa messge not found"))?; + let message = Uint8Array::from(js_message).to_vec(); + CoreNadaValue::new_eddsa_message(message) + } + "EddsaSignature" => { + let js_signature = js_sys::Reflect::get(&value, &JsValue::from("signature")) + .map_err(|_| JsError::new("Failed signature not found"))?; + let signature = Uint8Array::from(js_signature).to_vec(); + + let signature = signature::EddsaSignature::from_bytes(&signature)?; + CoreNadaValue::new_eddsa_signature(signature) + } + "EddsaPublicKey" => { + let js_public_key = js_sys::Reflect::get(&value, &JsValue::from("publicKey")) + .map_err(|_| JsError::new("Failed publicKey not found"))?; + let public_key: [u8; 32] = Uint8Array::from(js_public_key) + .to_vec() + .try_into() + .map_err(|_| JsError::new("eddsa public key must be 32 bytes"))?; + CoreNadaValue::new_eddsa_public_key(public_key) + } "StoreId" => { let js_store_id = js_sys::Reflect::get(&value, &JsValue::from("storeId")) .map_err(|_| JsError::new("Failed storeId not found"))?; @@ -845,16 +986,48 @@ impl EncryptedNadaValues { } Ok(EncryptedNadaValues(nada_values)) } + + fn json_to_private_key(value: &JsValue) -> JsResult> { + // i + let js_i = js_sys::Reflect::get(value, &JsValue::from("i")) + .map_err(|_| JsError::new("Failed i not found"))? + .as_string() + .unwrap_or_default(); + let i = u16::from_str(&js_i).map_err(|_| JsError::new("Invalid Ecdsa i"))?; + // x + let js_x = js_sys::Reflect::get(value, &JsValue::from("x")).map_err(|_| JsError::new("Failed x not found"))?; + let x = non_zero_secret_scalar_from_js_value(js_x)?; + // key_info + let js_shared_public_key = js_sys::Reflect::get(value, &JsValue::from("sharedPublicKey")) + .map_err(|_| JsError::new("Failed sharedPublicKey not found"))?; + let js_public_shares = js_sys::Reflect::get(value, &JsValue::from("publicShares")) + .map_err(|_| JsError::new("Failed publicShares not found"))?; + let key_info = DirtyKeyInfo { + curve: CurveName::new(), + shared_public_key: non_zero_point_from_js_value(js_shared_public_key)?, + public_shares: Array::from(&js_public_shares) + .to_vec() + .into_iter() + .map(non_zero_point_from_js_value) + .collect::>()?, + vss_setup: None, + }; + + let share = DirtyCoreKeyShare { i, key_info, x } + .validate() + .map_err(|e| JsError::new(&format!("invalid ecdsa private key: {e:?}")))?; + Ok(ThresholdPrivateKeyShare::new(share)) + } } -fn non_zero_point_from_js_value(js_value: JsValue) -> JsResult>> { +fn non_zero_point_from_js_value(js_value: JsValue) -> JsResult>> { let bytes = Uint8Array::from(js_value).to_vec(); let point = Point::from_bytes(&bytes).map_err(|_| JsError::new("Invalid ecdsa private key point: invalid bytes"))?; NonZero::from_point(point).ok_or(JsError::new("Invalid ecdsa private key point: point is zero")) } -fn non_zero_secret_scalar_from_js_value(js_value: JsValue) -> JsResult>> { +fn non_zero_secret_scalar_from_js_value(js_value: JsValue) -> JsResult>> { let bytes = Uint8Array::from(js_value).to_vec(); let scalar = SecretScalar::from_le_bytes(&bytes) .map_err(|_| JsError::new("Invalid ecdsa private key secret scalar: invalid bytes"))?; @@ -973,7 +1146,26 @@ mod test { values.insert("secret_unsigned_integer".into(), &NadaValue::new_secret_unsigned_integer("42")?); values.insert("secret_boolean".into(), &NadaValue::new_secret_boolean(true)?); values.insert("secret_blob".into(), &NadaValue::new_secret_blob(vec![1, 2, 3])); - values.insert("public_key".into(), &NadaValue::new_ecdsa_public_key(vec![1; 33])?); + values.insert("ecdsa_private_key".into(), &NadaValue::new_ecdsa_private_key(vec![1; 32])?); + values.insert("ecdsa_message".into(), &NadaValue::new_ecdsa_digest_message(vec![1; 32])?); + values.insert("ecdsa_public_key".into(), &NadaValue::new_ecdsa_public_key(vec![1; 33])?); + values.insert("ecdsa_signature".into(), &NadaValue::new_ecdsa_signature(vec![1; 32], vec![1; 32])?); + values.insert("eddsa_private_key".into(), &NadaValue::new_eddsa_private_key(vec![1; 32])?); + values.insert("eddsa_message".into(), &NadaValue::new_eddsa_message(vec![1; 32])?); + values.insert("eddsa_public_key".into(), &NadaValue::new_eddsa_public_key(vec![1; 32])?); + values.insert( + "eddsa_signature".into(), + &NadaValue::new_eddsa_signature( + vec![ + 228, 118, 63, 53, 138, 161, 20, 164, 93, 86, 233, 11, 211, 204, 186, 63, 255, 174, 220, 173, 222, + 58, 64, 79, 108, 173, 130, 1, 134, 44, 244, 104, + ], + vec![ + 137, 73, 233, 168, 34, 64, 148, 185, 177, 91, 184, 21, 246, 82, 65, 207, 83, 158, 44, 181, 199, 94, + 83, 178, 88, 238, 210, 220, 10, 49, 154, 1, + ], + )?, + ); values.insert("store_id".into(), &NadaValue::new_store_id(vec![1; 16])?); let masker = make_masker(); diff --git a/nilvm b/nilvm index c92a3b2c..d53b7295 160000 --- a/nilvm +++ b/nilvm @@ -1 +1 @@ -Subproject commit c92a3b2c3821f25915eb280513f402b3e04f18ff +Subproject commit d53b7295b7cdb3376af1186aa96915768a01223c