From 3375e38a9094ecf2565c2f49769eead5aae6577c Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Sat, 6 Jul 2024 16:54:25 -0300 Subject: [PATCH] [#64] Orchard Support Closes #64 This commit adds Orchard Support to the UniFFI FROST SDK: - Uses Orchard Repo Fork to expose `unstable-frost` feature - Enables Orchard viewing key string encoding - Exposes key elements needed to construct an FVK when an `ak` is provided - Exposes `OrchardCommitIvkRandomness` to the FFI - Fixes orchard key dependencies. - Adds swift test - Adds pipefail to scripts - Orchard Key tests for Go Lang --- .../Extensions/FrostSwift+Orchard.swift | 22 + .../FrostSwiftFFI/frost_uniffi_sdk.swift | 736 +++++++++ .../OrchardSwiftTests.swift | 66 + Package.resolved | 16 + Package.swift | 17 +- Scripts/build_go.sh | 2 +- Scripts/build_go_bindings.sh | 2 +- Scripts/build_randomized_go.sh | 2 +- Scripts/build_swift.sh | 2 +- Scripts/replace_remote_binary_with_local.sh | 2 +- Scripts/test_bindings.sh | 2 +- Scripts/test_randomized_bindings.sh | 8 +- Scripts/test_swift.sh | 2 +- frost-uniffi-sdk/Cargo.toml | 13 + frost-uniffi-sdk/src/lib.rs | 1 + frost-uniffi-sdk/src/orchard/keys.rs | 461 ++++++ frost-uniffi-sdk/src/orchard/lib.rs | 3 + frost-uniffi-sdk/src/orchard/mod.rs | 2 + frost-uniffi-sdk/tests/helpers.rs | 1 + frost-uniffi-sdk/tests/integration_tests.rs | 3 +- .../tests/randomized_integration_tests.rs | 2 +- frost_go_ffi/frost_go_ffi.h | 328 ++++ .../frost_go_ffi_orchard_keys_test.go | 89 ++ frost_go_ffi/frost_uniffi_sdk.go | 1354 ++++++++++++++++- 24 files changed, 3065 insertions(+), 71 deletions(-) create mode 100644 FrostSwift/Sources/FrostSwift/Extensions/FrostSwift+Orchard.swift create mode 100644 FrostSwift/Tests/OrchardSwiftFFI/OrchardSwiftFFITests/OrchardSwiftTests.swift create mode 100644 Package.resolved create mode 100644 frost-uniffi-sdk/src/orchard/keys.rs create mode 100644 frost-uniffi-sdk/src/orchard/lib.rs create mode 100644 frost-uniffi-sdk/src/orchard/mod.rs create mode 100644 frost_go_ffi/frost_go_ffi_orchard_keys_test.go diff --git a/FrostSwift/Sources/FrostSwift/Extensions/FrostSwift+Orchard.swift b/FrostSwift/Sources/FrostSwift/Extensions/FrostSwift+Orchard.swift new file mode 100644 index 0000000..bbe4fd1 --- /dev/null +++ b/FrostSwift/Sources/FrostSwift/Extensions/FrostSwift+Orchard.swift @@ -0,0 +1,22 @@ +// +// FrostSwift+Orchard.swift +// +// +// Created by pacu on 2024-08-17. +// + +import FrostSwiftFFI + +extension OrchardFullViewingKey: Equatable { + /// This method checks the equality of the UFVK by verifying that the encoded String is the same + /// this means that it will return true if the UFVK has the same viewing keys + /// - Note: Not really efficient. + /// - Returns: true if the encodings are the same. False if not or if any of the two throw. + public static func == (lhs: FrostSwiftFFI.OrchardFullViewingKey, rhs: FrostSwiftFFI.OrchardFullViewingKey) -> Bool { + guard let lhs = try? lhs.encode(), let rhs = try? rhs.encode() else { + return false + } + + return lhs == rhs + } +} diff --git a/FrostSwift/Sources/FrostSwiftFFI/frost_uniffi_sdk.swift b/FrostSwift/Sources/FrostSwiftFFI/frost_uniffi_sdk.swift index 540dbe5..9a111c4 100644 --- a/FrostSwift/Sources/FrostSwiftFFI/frost_uniffi_sdk.swift +++ b/FrostSwift/Sources/FrostSwiftFFI/frost_uniffi_sdk.swift @@ -684,6 +684,568 @@ public func FfiConverterTypeFrostRandomizedParams_lower(_ value: FrostRandomized } +public protocol OrchardAddressProtocol { + func stringEncoded() -> String + +} + +public class OrchardAddress: OrchardAddressProtocol { + fileprivate let pointer: UnsafeMutableRawPointer + + // TODO: We'd like this to be `private` but for Swifty reasons, + // we can't implement `FfiConverter` without making this `required` and we can't + // make it `required` without making it `public`. + required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { + self.pointer = pointer + } + + deinit { + try! rustCall { uniffi_frost_uniffi_sdk_fn_free_orchardaddress(pointer, $0) } + } + + + + public static func newFromString(string: String) throws -> OrchardAddress { + return OrchardAddress(unsafeFromRawPointer: try rustCallWithError(FfiConverterTypeOrchardKeyError.lift) { + uniffi_frost_uniffi_sdk_fn_constructor_orchardaddress_new_from_string( + FfiConverterString.lower(string),$0) +}) + } + + + + + + + public func stringEncoded() -> String { + return try! FfiConverterString.lift( + try! + rustCall() { + + uniffi_frost_uniffi_sdk_fn_method_orchardaddress_string_encoded(self.pointer, $0 + ) +} + ) + } +} + +public struct FfiConverterTypeOrchardAddress: FfiConverter { + typealias FfiType = UnsafeMutableRawPointer + typealias SwiftType = OrchardAddress + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrchardAddress { + let v: UInt64 = try readInt(&buf) + // The Rust code won't compile if a pointer won't fit in a UInt64. + // We have to go via `UInt` because that's the thing that's the size of a pointer. + let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v)) + if (ptr == nil) { + throw UniffiInternalError.unexpectedNullPointer + } + return try lift(ptr!) + } + + public static func write(_ value: OrchardAddress, into buf: inout [UInt8]) { + // This fiddling is because `Int` is the thing that's the same size as a pointer. + // The Rust code won't compile if a pointer won't fit in a `UInt64`. + writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value))))) + } + + public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardAddress { + return OrchardAddress(unsafeFromRawPointer: pointer) + } + + public static func lower(_ value: OrchardAddress) -> UnsafeMutableRawPointer { + return value.pointer + } +} + + +public func FfiConverterTypeOrchardAddress_lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardAddress { + return try FfiConverterTypeOrchardAddress.lift(pointer) +} + +public func FfiConverterTypeOrchardAddress_lower(_ value: OrchardAddress) -> UnsafeMutableRawPointer { + return FfiConverterTypeOrchardAddress.lower(value) +} + + +public protocol OrchardCommitIvkRandomnessProtocol { + func toBytes() -> Data + +} + +public class OrchardCommitIvkRandomness: OrchardCommitIvkRandomnessProtocol { + fileprivate let pointer: UnsafeMutableRawPointer + + // TODO: We'd like this to be `private` but for Swifty reasons, + // we can't implement `FfiConverter` without making this `required` and we can't + // make it `required` without making it `public`. + required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { + self.pointer = pointer + } + public convenience init(bytes: Data) throws { + self.init(unsafeFromRawPointer: try rustCallWithError(FfiConverterTypeOrchardKeyError.lift) { + uniffi_frost_uniffi_sdk_fn_constructor_orchardcommitivkrandomness_new( + FfiConverterData.lower(bytes),$0) +}) + } + + deinit { + try! rustCall { uniffi_frost_uniffi_sdk_fn_free_orchardcommitivkrandomness(pointer, $0) } + } + + + + + + + public func toBytes() -> Data { + return try! FfiConverterData.lift( + try! + rustCall() { + + uniffi_frost_uniffi_sdk_fn_method_orchardcommitivkrandomness_to_bytes(self.pointer, $0 + ) +} + ) + } +} + +public struct FfiConverterTypeOrchardCommitIvkRandomness: FfiConverter { + typealias FfiType = UnsafeMutableRawPointer + typealias SwiftType = OrchardCommitIvkRandomness + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrchardCommitIvkRandomness { + let v: UInt64 = try readInt(&buf) + // The Rust code won't compile if a pointer won't fit in a UInt64. + // We have to go via `UInt` because that's the thing that's the size of a pointer. + let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v)) + if (ptr == nil) { + throw UniffiInternalError.unexpectedNullPointer + } + return try lift(ptr!) + } + + public static func write(_ value: OrchardCommitIvkRandomness, into buf: inout [UInt8]) { + // This fiddling is because `Int` is the thing that's the same size as a pointer. + // The Rust code won't compile if a pointer won't fit in a `UInt64`. + writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value))))) + } + + public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardCommitIvkRandomness { + return OrchardCommitIvkRandomness(unsafeFromRawPointer: pointer) + } + + public static func lower(_ value: OrchardCommitIvkRandomness) -> UnsafeMutableRawPointer { + return value.pointer + } +} + + +public func FfiConverterTypeOrchardCommitIvkRandomness_lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardCommitIvkRandomness { + return try FfiConverterTypeOrchardCommitIvkRandomness.lift(pointer) +} + +public func FfiConverterTypeOrchardCommitIvkRandomness_lower(_ value: OrchardCommitIvkRandomness) -> UnsafeMutableRawPointer { + return FfiConverterTypeOrchardCommitIvkRandomness.lower(value) +} + + +public protocol OrchardFullViewingKeyProtocol { + func ak() -> OrchardSpendValidatingKey + func deriveAddress() throws -> OrchardAddress + func encode() throws -> String + func nk() -> OrchardNullifierDerivingKey + func rivk() -> OrchardCommitIvkRandomness + +} + +public class OrchardFullViewingKey: OrchardFullViewingKeyProtocol { + fileprivate let pointer: UnsafeMutableRawPointer + + // TODO: We'd like this to be `private` but for Swifty reasons, + // we can't implement `FfiConverter` without making this `required` and we can't + // make it `required` without making it `public`. + required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { + self.pointer = pointer + } + + deinit { + try! rustCall { uniffi_frost_uniffi_sdk_fn_free_orchardfullviewingkey(pointer, $0) } + } + + + + public static func decode(stringEnconded: String, network: ZcashNetwork) throws -> OrchardFullViewingKey { + return OrchardFullViewingKey(unsafeFromRawPointer: try rustCallWithError(FfiConverterTypeOrchardKeyError.lift) { + uniffi_frost_uniffi_sdk_fn_constructor_orchardfullviewingkey_decode( + FfiConverterString.lower(stringEnconded), + FfiConverterTypeZcashNetwork.lower(network),$0) +}) + } + + + + public static func newFromCheckedParts(ak: OrchardSpendValidatingKey, nk: OrchardNullifierDerivingKey, rivk: OrchardCommitIvkRandomness, network: ZcashNetwork) throws -> OrchardFullViewingKey { + return OrchardFullViewingKey(unsafeFromRawPointer: try rustCallWithError(FfiConverterTypeOrchardKeyError.lift) { + uniffi_frost_uniffi_sdk_fn_constructor_orchardfullviewingkey_new_from_checked_parts( + FfiConverterTypeOrchardSpendValidatingKey.lower(ak), + FfiConverterTypeOrchardNullifierDerivingKey.lower(nk), + FfiConverterTypeOrchardCommitIvkRandomness.lower(rivk), + FfiConverterTypeZcashNetwork.lower(network),$0) +}) + } + + + + public static func newFromValidatingKeyAndSeed(validatingKey: OrchardSpendValidatingKey, zip32Seed: Data, network: ZcashNetwork) throws -> OrchardFullViewingKey { + return OrchardFullViewingKey(unsafeFromRawPointer: try rustCallWithError(FfiConverterTypeOrchardKeyError.lift) { + uniffi_frost_uniffi_sdk_fn_constructor_orchardfullviewingkey_new_from_validating_key_and_seed( + FfiConverterTypeOrchardSpendValidatingKey.lower(validatingKey), + FfiConverterData.lower(zip32Seed), + FfiConverterTypeZcashNetwork.lower(network),$0) +}) + } + + + + + + + public func ak() -> OrchardSpendValidatingKey { + return try! FfiConverterTypeOrchardSpendValidatingKey.lift( + try! + rustCall() { + + uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_ak(self.pointer, $0 + ) +} + ) + } + + public func deriveAddress() throws -> OrchardAddress { + return try FfiConverterTypeOrchardAddress.lift( + try + rustCallWithError(FfiConverterTypeOrchardKeyError.lift) { + uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_derive_address(self.pointer, $0 + ) +} + ) + } + + public func encode() throws -> String { + return try FfiConverterString.lift( + try + rustCallWithError(FfiConverterTypeOrchardKeyError.lift) { + uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_encode(self.pointer, $0 + ) +} + ) + } + + public func nk() -> OrchardNullifierDerivingKey { + return try! FfiConverterTypeOrchardNullifierDerivingKey.lift( + try! + rustCall() { + + uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_nk(self.pointer, $0 + ) +} + ) + } + + public func rivk() -> OrchardCommitIvkRandomness { + return try! FfiConverterTypeOrchardCommitIvkRandomness.lift( + try! + rustCall() { + + uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_rivk(self.pointer, $0 + ) +} + ) + } +} + +public struct FfiConverterTypeOrchardFullViewingKey: FfiConverter { + typealias FfiType = UnsafeMutableRawPointer + typealias SwiftType = OrchardFullViewingKey + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrchardFullViewingKey { + let v: UInt64 = try readInt(&buf) + // The Rust code won't compile if a pointer won't fit in a UInt64. + // We have to go via `UInt` because that's the thing that's the size of a pointer. + let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v)) + if (ptr == nil) { + throw UniffiInternalError.unexpectedNullPointer + } + return try lift(ptr!) + } + + public static func write(_ value: OrchardFullViewingKey, into buf: inout [UInt8]) { + // This fiddling is because `Int` is the thing that's the same size as a pointer. + // The Rust code won't compile if a pointer won't fit in a `UInt64`. + writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value))))) + } + + public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardFullViewingKey { + return OrchardFullViewingKey(unsafeFromRawPointer: pointer) + } + + public static func lower(_ value: OrchardFullViewingKey) -> UnsafeMutableRawPointer { + return value.pointer + } +} + + +public func FfiConverterTypeOrchardFullViewingKey_lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardFullViewingKey { + return try FfiConverterTypeOrchardFullViewingKey.lift(pointer) +} + +public func FfiConverterTypeOrchardFullViewingKey_lower(_ value: OrchardFullViewingKey) -> UnsafeMutableRawPointer { + return FfiConverterTypeOrchardFullViewingKey.lower(value) +} + + +public protocol OrchardKeyPartsProtocol { + +} + +public class OrchardKeyParts: OrchardKeyPartsProtocol { + fileprivate let pointer: UnsafeMutableRawPointer + + // TODO: We'd like this to be `private` but for Swifty reasons, + // we can't implement `FfiConverter` without making this `required` and we can't + // make it `required` without making it `public`. + required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { + self.pointer = pointer + } + + deinit { + try! rustCall { uniffi_frost_uniffi_sdk_fn_free_orchardkeyparts(pointer, $0) } + } + + + + public static func random(network: ZcashNetwork) throws -> OrchardKeyParts { + return OrchardKeyParts(unsafeFromRawPointer: try rustCallWithError(FfiConverterTypeOrchardKeyError.lift) { + uniffi_frost_uniffi_sdk_fn_constructor_orchardkeyparts_random( + FfiConverterTypeZcashNetwork.lower(network),$0) +}) + } + + + + + +} + +public struct FfiConverterTypeOrchardKeyParts: FfiConverter { + typealias FfiType = UnsafeMutableRawPointer + typealias SwiftType = OrchardKeyParts + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrchardKeyParts { + let v: UInt64 = try readInt(&buf) + // The Rust code won't compile if a pointer won't fit in a UInt64. + // We have to go via `UInt` because that's the thing that's the size of a pointer. + let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v)) + if (ptr == nil) { + throw UniffiInternalError.unexpectedNullPointer + } + return try lift(ptr!) + } + + public static func write(_ value: OrchardKeyParts, into buf: inout [UInt8]) { + // This fiddling is because `Int` is the thing that's the same size as a pointer. + // The Rust code won't compile if a pointer won't fit in a `UInt64`. + writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value))))) + } + + public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardKeyParts { + return OrchardKeyParts(unsafeFromRawPointer: pointer) + } + + public static func lower(_ value: OrchardKeyParts) -> UnsafeMutableRawPointer { + return value.pointer + } +} + + +public func FfiConverterTypeOrchardKeyParts_lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardKeyParts { + return try FfiConverterTypeOrchardKeyParts.lift(pointer) +} + +public func FfiConverterTypeOrchardKeyParts_lower(_ value: OrchardKeyParts) -> UnsafeMutableRawPointer { + return FfiConverterTypeOrchardKeyParts.lower(value) +} + + +public protocol OrchardNullifierDerivingKeyProtocol { + func toBytes() -> Data + +} + +public class OrchardNullifierDerivingKey: OrchardNullifierDerivingKeyProtocol { + fileprivate let pointer: UnsafeMutableRawPointer + + // TODO: We'd like this to be `private` but for Swifty reasons, + // we can't implement `FfiConverter` without making this `required` and we can't + // make it `required` without making it `public`. + required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { + self.pointer = pointer + } + public convenience init(bytes: Data) throws { + self.init(unsafeFromRawPointer: try rustCallWithError(FfiConverterTypeOrchardKeyError.lift) { + uniffi_frost_uniffi_sdk_fn_constructor_orchardnullifierderivingkey_new( + FfiConverterData.lower(bytes),$0) +}) + } + + deinit { + try! rustCall { uniffi_frost_uniffi_sdk_fn_free_orchardnullifierderivingkey(pointer, $0) } + } + + + + + + + public func toBytes() -> Data { + return try! FfiConverterData.lift( + try! + rustCall() { + + uniffi_frost_uniffi_sdk_fn_method_orchardnullifierderivingkey_to_bytes(self.pointer, $0 + ) +} + ) + } +} + +public struct FfiConverterTypeOrchardNullifierDerivingKey: FfiConverter { + typealias FfiType = UnsafeMutableRawPointer + typealias SwiftType = OrchardNullifierDerivingKey + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrchardNullifierDerivingKey { + let v: UInt64 = try readInt(&buf) + // The Rust code won't compile if a pointer won't fit in a UInt64. + // We have to go via `UInt` because that's the thing that's the size of a pointer. + let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v)) + if (ptr == nil) { + throw UniffiInternalError.unexpectedNullPointer + } + return try lift(ptr!) + } + + public static func write(_ value: OrchardNullifierDerivingKey, into buf: inout [UInt8]) { + // This fiddling is because `Int` is the thing that's the same size as a pointer. + // The Rust code won't compile if a pointer won't fit in a `UInt64`. + writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value))))) + } + + public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardNullifierDerivingKey { + return OrchardNullifierDerivingKey(unsafeFromRawPointer: pointer) + } + + public static func lower(_ value: OrchardNullifierDerivingKey) -> UnsafeMutableRawPointer { + return value.pointer + } +} + + +public func FfiConverterTypeOrchardNullifierDerivingKey_lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardNullifierDerivingKey { + return try FfiConverterTypeOrchardNullifierDerivingKey.lift(pointer) +} + +public func FfiConverterTypeOrchardNullifierDerivingKey_lower(_ value: OrchardNullifierDerivingKey) -> UnsafeMutableRawPointer { + return FfiConverterTypeOrchardNullifierDerivingKey.lower(value) +} + + +public protocol OrchardSpendValidatingKeyProtocol { + func toBytes() -> Data + +} + +public class OrchardSpendValidatingKey: OrchardSpendValidatingKeyProtocol { + fileprivate let pointer: UnsafeMutableRawPointer + + // TODO: We'd like this to be `private` but for Swifty reasons, + // we can't implement `FfiConverter` without making this `required` and we can't + // make it `required` without making it `public`. + required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { + self.pointer = pointer + } + + deinit { + try! rustCall { uniffi_frost_uniffi_sdk_fn_free_orchardspendvalidatingkey(pointer, $0) } + } + + + + public static func fromBytes(bytes: Data) throws -> OrchardSpendValidatingKey { + return OrchardSpendValidatingKey(unsafeFromRawPointer: try rustCallWithError(FfiConverterTypeOrchardKeyError.lift) { + uniffi_frost_uniffi_sdk_fn_constructor_orchardspendvalidatingkey_from_bytes( + FfiConverterData.lower(bytes),$0) +}) + } + + + + + + + public func toBytes() -> Data { + return try! FfiConverterData.lift( + try! + rustCall() { + + uniffi_frost_uniffi_sdk_fn_method_orchardspendvalidatingkey_to_bytes(self.pointer, $0 + ) +} + ) + } +} + +public struct FfiConverterTypeOrchardSpendValidatingKey: FfiConverter { + typealias FfiType = UnsafeMutableRawPointer + typealias SwiftType = OrchardSpendValidatingKey + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrchardSpendValidatingKey { + let v: UInt64 = try readInt(&buf) + // The Rust code won't compile if a pointer won't fit in a UInt64. + // We have to go via `UInt` because that's the thing that's the size of a pointer. + let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v)) + if (ptr == nil) { + throw UniffiInternalError.unexpectedNullPointer + } + return try lift(ptr!) + } + + public static func write(_ value: OrchardSpendValidatingKey, into buf: inout [UInt8]) { + // This fiddling is because `Int` is the thing that's the same size as a pointer. + // The Rust code won't compile if a pointer won't fit in a `UInt64`. + writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value))))) + } + + public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardSpendValidatingKey { + return OrchardSpendValidatingKey(unsafeFromRawPointer: pointer) + } + + public static func lower(_ value: OrchardSpendValidatingKey) -> UnsafeMutableRawPointer { + return value.pointer + } +} + + +public func FfiConverterTypeOrchardSpendValidatingKey_lift(_ pointer: UnsafeMutableRawPointer) throws -> OrchardSpendValidatingKey { + return try FfiConverterTypeOrchardSpendValidatingKey.lift(pointer) +} + +public func FfiConverterTypeOrchardSpendValidatingKey_lower(_ value: OrchardSpendValidatingKey) -> UnsafeMutableRawPointer { + return FfiConverterTypeOrchardSpendValidatingKey.lower(value) +} + + public struct Configuration { public var minSigners: UInt16 public var maxSigners: UInt16 @@ -2125,6 +2687,77 @@ extension FrostSignatureVerificationError: Equatable, Hashable {} extension FrostSignatureVerificationError: Error { } +public enum OrchardKeyError { + + + + case KeyDerivationError(message: String) + case SerializationError + case DeserializationError + case OtherError(errorMessage: String) + + fileprivate static func uniffiErrorHandler(_ error: RustBuffer) throws -> Error { + return try FfiConverterTypeOrchardKeyError.lift(error) + } +} + + +public struct FfiConverterTypeOrchardKeyError: FfiConverterRustBuffer { + typealias SwiftType = OrchardKeyError + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrchardKeyError { + let variant: Int32 = try readInt(&buf) + switch variant { + + + + + case 1: return .KeyDerivationError( + message: try FfiConverterString.read(from: &buf) + ) + case 2: return .SerializationError + case 3: return .DeserializationError + case 4: return .OtherError( + errorMessage: try FfiConverterString.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: OrchardKeyError, into buf: inout [UInt8]) { + switch value { + + + + + + case let .KeyDerivationError(message): + writeInt(&buf, Int32(1)) + FfiConverterString.write(message, into: &buf) + + + case .SerializationError: + writeInt(&buf, Int32(2)) + + + case .DeserializationError: + writeInt(&buf, Int32(3)) + + + case let .OtherError(errorMessage): + writeInt(&buf, Int32(4)) + FfiConverterString.write(errorMessage, into: &buf) + + } + } +} + + +extension OrchardKeyError: Equatable, Hashable {} + +extension OrchardKeyError: Error { } + public enum Round1Error { @@ -2264,6 +2897,58 @@ extension Round2Error: Equatable, Hashable {} extension Round2Error: Error { } +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +public enum ZcashNetwork { + + case mainnet + case testnet +} + +public struct FfiConverterTypeZcashNetwork: FfiConverterRustBuffer { + typealias SwiftType = ZcashNetwork + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ZcashNetwork { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .mainnet + + case 2: return .testnet + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: ZcashNetwork, into buf: inout [UInt8]) { + switch value { + + + case .mainnet: + writeInt(&buf, Int32(1)) + + + case .testnet: + writeInt(&buf, Int32(2)) + + } + } +} + + +public func FfiConverterTypeZcashNetwork_lift(_ buf: RustBuffer) throws -> ZcashNetwork { + return try FfiConverterTypeZcashNetwork.lift(buf) +} + +public func FfiConverterTypeZcashNetwork_lower(_ value: ZcashNetwork) -> RustBuffer { + return FfiConverterTypeZcashNetwork.lower(value) +} + + +extension ZcashNetwork: Equatable, Hashable {} + + + fileprivate struct FfiConverterOptionTypeParticipantIdentifier: FfiConverterRustBuffer { typealias SwiftType = ParticipantIdentifier? @@ -2827,6 +3512,57 @@ private var initializationResult: InitializationResult { if (uniffi_frost_uniffi_sdk_checksum_func_verify_signature() != 13620) { return InitializationResult.apiChecksumMismatch } + if (uniffi_frost_uniffi_sdk_checksum_method_orchardaddress_string_encoded() != 38758) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_method_orchardcommitivkrandomness_to_bytes() != 54004) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_ak() != 1900) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_derive_address() != 26015) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_encode() != 34271) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_nk() != 33472) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_rivk() != 25054) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_method_orchardnullifierderivingkey_to_bytes() != 8783) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_method_orchardspendvalidatingkey_to_bytes() != 10051) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_constructor_orchardaddress_new_from_string() != 64287) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_constructor_orchardcommitivkrandomness_new() != 55160) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_decode() != 6758) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_new_from_checked_parts() != 19481) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_new_from_validating_key_and_seed() != 62836) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_constructor_orchardkeyparts_random() != 3046) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_constructor_orchardnullifierderivingkey_new() != 15347) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_frost_uniffi_sdk_checksum_constructor_orchardspendvalidatingkey_from_bytes() != 63121) { + return InitializationResult.apiChecksumMismatch + } return InitializationResult.ok } diff --git a/FrostSwift/Tests/OrchardSwiftFFI/OrchardSwiftFFITests/OrchardSwiftTests.swift b/FrostSwift/Tests/OrchardSwiftFFI/OrchardSwiftFFITests/OrchardSwiftTests.swift new file mode 100644 index 0000000..fd53b02 --- /dev/null +++ b/FrostSwift/Tests/OrchardSwiftFFI/OrchardSwiftFFITests/OrchardSwiftTests.swift @@ -0,0 +1,66 @@ +// +// OrchardSwiftTests.swift +// +// +// Created by Pacu in 2024. +// + + +import XCTest +import Foundation +import CryptoSwift +@testable import FrostSwiftFFI +import FrostSwift +final class OrchardSwiftTests: XCTestCase { + /// This test verifies that the APIs succeed at creating a Full viewing key from a validating key + /// and a ZIP 32 seed. this should be done other than for viewing key creation that is tossed. + func testUFVKandAddressAreDerivedfromSeed() throws { + + let hexStringAk = "d2bf40ca860fb97e9d6d15d7d25e4f17d2e8ba5dd7069188cbf30b023910a71b" + let hexAk = [UInt8](hex: hexStringAk) + let ak = try OrchardSpendValidatingKey.fromBytes(bytes: Data(hexAk)) + + let randomSeedBytesHexString = "659ce2e5362b515f30c38807942a10c18a3a2f7584e7135b3523d5e72bb796cc64c366a8a6bfb54a5b32c41720bdb135758c1afacac3e72fd5974be0846bf7a5" + + let randomSeedbytes = [UInt8](hex: randomSeedBytesHexString) + let zcashNetwork = ZcashNetwork.testnet + + let fvk = try OrchardFullViewingKey.newFromValidatingKeyAndSeed( + validatingKey: ak, + zip32Seed: Data(randomSeedbytes), + network: zcashNetwork + ) + + XCTAssertEqual( + "uviewtest1jd7ucm0fdh9s0gqk9cse9xtqcyycj2k06krm3l9r6snakdzqz5tdp3ua4nerj8uttfepzjxrhp9a4c3wl7h508fmjwqgmqgvslcgvc8htqzm8gg5h9sygqt76un40xvzyyk7fvlestphmmz9emyqhjkl60u4dx25t86lhs30jreghq40cfnw9nqh858z4", + try fvk.encode() + ) + + let address = try fvk.deriveAddress() + + XCTAssertEqual( + "utest1fqasmz9zpaq3qlg4ghy6r5cf6u3qsvdrty9q6e4jh4sxd2ztryy0nvp59jpu5npaqwrgf7sgqu9z7hz9sdxw22vdpay4v4mm8vv2hlg4", + address.stringEncoded() + ) + } + + /// This tests that an Orchard UFVK can actually be decomposed into its parts. + func testUFVKIsDecomposedOnParts() throws { + let ufvkString = "uviewtest1jd7ucm0fdh9s0gqk9cse9xtqcyycj2k06krm3l9r6snakdzqz5tdp3ua4nerj8uttfepzjxrhp9a4c3wl7h508fmjwqgmqgvslcgvc8htqzm8gg5h9sygqt76un40xvzyyk7fvlestphmmz9emyqhjkl60u4dx25t86lhs30jreghq40cfnw9nqh858z4" + + let ufvk = try OrchardFullViewingKey.decode(stringEnconded: ufvkString, network: .testnet) + + let nk = ufvk.nk() + let ak = ufvk.ak() + let rivk = ufvk.rivk() + + let roundtripUFVK = try OrchardFullViewingKey.newFromCheckedParts( + ak: ak, + nk: nk, + rivk: rivk, + network: .testnet + ) + + XCTAssertEqual(ufvk, roundtripUFVK) + } +} diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..4d0ddcf --- /dev/null +++ b/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "CryptoSwift", + "repositoryURL": "https://github.com/krzyzanowskim/CryptoSwift", + "state": { + "branch": null, + "revision": "678d442c6f7828def400a70ae15968aef67ef52d", + "version": "1.8.3" + } + } + ] + }, + "version": 1 +} diff --git a/Package.swift b/Package.swift index afacac2..cc9c365 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,9 @@ let package = Package( targets: ["FrostSwiftFFI"] ) ], - dependencies: [ ], + dependencies: [ + .package(url: "https://github.com/krzyzanowskim/CryptoSwift", from: "1.8.3") + ], targets: [ .target( name: "FrostSwift", @@ -33,13 +35,24 @@ let package = Package( ), .testTarget( name: "NotRedPallasTests", - dependencies: ["FrostSwiftFFI"], + dependencies: [ + "FrostSwiftFFI", + ], path: "FrostSwift/Tests/FrostSwiftFFI" ), .testTarget( name: "FrostTests", dependencies: ["FrostSwift"], path: "FrostSwift/Tests/FrostSwift" + ), + .testTarget( + name: "OrchardSwiftFFITests", + dependencies: [ + "FrostSwift", + "FrostSwiftFFI", + "CryptoSwift" + ], + path: "FrostSwift/Tests/OrchardSwiftFFI" ) ] ) diff --git a/Scripts/build_go.sh b/Scripts/build_go.sh index ec14ea8..6e84865 100644 --- a/Scripts/build_go.sh +++ b/Scripts/build_go.sh @@ -1,4 +1,4 @@ #!/bin/sh - +set -euxo pipefail cargo build --package frost-uniffi-sdk --no-default-features cargo build --package uniffi-bindgen diff --git a/Scripts/build_go_bindings.sh b/Scripts/build_go_bindings.sh index 311f5a9..0b32694 100644 --- a/Scripts/build_go_bindings.sh +++ b/Scripts/build_go_bindings.sh @@ -1,5 +1,5 @@ #!/bin/sh - +set -euxo pipefail cargo install uniffi-bindgen-go --git https://github.com/NordSecurity/uniffi-bindgen-go --tag v0.2.1+v0.25.0 uniffi-bindgen-go --library './target/debug/libfrost_uniffi_sdk.dylib' --out-dir . \ No newline at end of file diff --git a/Scripts/build_randomized_go.sh b/Scripts/build_randomized_go.sh index 000cd8e..b064d39 100644 --- a/Scripts/build_randomized_go.sh +++ b/Scripts/build_randomized_go.sh @@ -1,3 +1,3 @@ #!/bin/sh - +set -euxo pipefail cargo build --package frost-uniffi-sdk --package uniffi-bindgen --features redpallas diff --git a/Scripts/build_swift.sh b/Scripts/build_swift.sh index e70fa07..169a0b1 100644 --- a/Scripts/build_swift.sh +++ b/Scripts/build_swift.sh @@ -1,5 +1,5 @@ #!/bin/sh - +set -euxo pipefail # this builds randomized frost by default because cargo-swift 0.5 does not have the cd frost-uniffi-sdk cargo install cargo-swift@=0.5 -f diff --git a/Scripts/replace_remote_binary_with_local.sh b/Scripts/replace_remote_binary_with_local.sh index 7ac58c7..e21a3e2 100644 --- a/Scripts/replace_remote_binary_with_local.sh +++ b/Scripts/replace_remote_binary_with_local.sh @@ -1,5 +1,5 @@ #!/bin/sh - +set -euxo pipefail if [[ "$OSTYPE" == "darwin"* ]]; then sed -i '' 's|^[[:space:]]*\.binaryTarget(name: "RustFramework", url: "[^"]*", checksum: "[^"]*")\,| .binaryTarget(name: "RustFramework", path: "FrostSwift/RustFramework.xcframework.zip"),|' Package.swift diff --git a/Scripts/test_bindings.sh b/Scripts/test_bindings.sh index 730a894..48aec34 100755 --- a/Scripts/test_bindings.sh +++ b/Scripts/test_bindings.sh @@ -1,5 +1,5 @@ #!/bin/bash - +set -euxo pipefail ROOT_DIR=$(pwd) SCRIPT_DIR="${SCRIPT_DIR:-$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )}" diff --git a/Scripts/test_randomized_bindings.sh b/Scripts/test_randomized_bindings.sh index 7267b84..95cdf25 100755 --- a/Scripts/test_randomized_bindings.sh +++ b/Scripts/test_randomized_bindings.sh @@ -1,5 +1,5 @@ #!/bin/bash - +set -euxo pipefail ROOT_DIR=$(pwd) SCRIPT_DIR="${SCRIPT_DIR:-$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )}" @@ -11,4 +11,8 @@ pushd $BINDINGS_DIR LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}:$BINARIES_DIR" \ CGO_LDFLAGS="-lfrost_uniffi_sdk -L$BINARIES_DIR -lm -ldl" \ CGO_ENABLED=1 \ - go test -v $BINDINGS_DIR/frost_go_ffi_randomized_test.go $BINDINGS_DIR/frost_uniffi_sdk.go \ No newline at end of file + go test -v $BINDINGS_DIR/frost_go_ffi_randomized_test.go $BINDINGS_DIR/frost_uniffi_sdk.go +LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}:$BINARIES_DIR" \ + CGO_LDFLAGS="-lfrost_uniffi_sdk -L$BINARIES_DIR -lm -ldl" \ + CGO_ENABLED=1 \ + go test -v $BINDINGS_DIR/frost_go_ffi_orchard_keys_test.go $BINDINGS_DIR/frost_uniffi_sdk.go \ No newline at end of file diff --git a/Scripts/test_swift.sh b/Scripts/test_swift.sh index aa1c601..94c7129 100644 --- a/Scripts/test_swift.sh +++ b/Scripts/test_swift.sh @@ -1,5 +1,5 @@ #!/bin/sh - +set -euxo pipefail sh Scripts/build_swift.sh sh Scripts/replace_remote_binary_with_local.sh diff --git a/frost-uniffi-sdk/Cargo.toml b/frost-uniffi-sdk/Cargo.toml index 3bee61a..d11d9b9 100644 --- a/frost-uniffi-sdk/Cargo.toml +++ b/frost-uniffi-sdk/Cargo.toml @@ -19,8 +19,21 @@ serde_json = { workspace = true } rand = { workspace = true } hex = { workspace = true } +# Zcash dependencies +orchard = { git = "https://github.com/pacu/orchard", rev = "d0d6d2c1ab141d503725d0691e9f4318797558f6", features = ["unstable-frost"] } +zcash_primitives = { git = "https://github.com/pacu/librustzcash", rev = "be8444bde5494bfd3d3ab03953f5ef31ba976c4e" } +zcash_protocol = { git = "https://github.com/pacu/librustzcash", rev = "be8444bde5494bfd3d3ab03953f5ef31ba976c4e" } +zcash_keys = { git = "https://github.com/pacu/librustzcash", rev = "be8444bde5494bfd3d3ab03953f5ef31ba976c4e", features = ["orchard", "unstable-frost"] } +zip32 = "0.1" +zcash_address = { git = "https://github.com/pacu/librustzcash", rev = "be8444bde5494bfd3d3ab03953f5ef31ba976c4e" } + +# Other dependencies +bip0039 = "0.11" + + [features] redpallas = [] +regtest = [] default = ["redpallas"] [build-dependencies] diff --git a/frost-uniffi-sdk/src/lib.rs b/frost-uniffi-sdk/src/lib.rs index 40f3596..abd88af 100644 --- a/frost-uniffi-sdk/src/lib.rs +++ b/frost-uniffi-sdk/src/lib.rs @@ -10,6 +10,7 @@ pub mod participant; pub mod randomized; pub mod serialization; pub mod trusted_dealer; +pub mod orchard; use crate::trusted_dealer::{trusted_dealer_keygen, trusted_dealer_keygen_from_configuration}; use frost_core::{ diff --git a/frost-uniffi-sdk/src/orchard/keys.rs b/frost-uniffi-sdk/src/orchard/keys.rs new file mode 100644 index 0000000..57aa47c --- /dev/null +++ b/frost-uniffi-sdk/src/orchard/keys.rs @@ -0,0 +1,461 @@ +use bip0039::{English, Mnemonic}; +use std::sync::Arc; +use uniffi::{self}; + +use orchard::keys::{ + CommitIvkRandomness, FullViewingKey, NullifierDerivingKey, + SpendValidatingKey, SpendingKey, +}; +use zcash_address::unified::{Address, Encoding, Receiver}; +use zcash_keys::keys::UnifiedFullViewingKey; +use zcash_primitives::zip32::AccountId; +use zcash_protocol::consensus::{Network, NetworkConstants, NetworkType}; +use zip32::Scope; + +#[derive(uniffi::Enum, Clone, Debug)] +pub enum ZcashNetwork { + Mainnet, + Testnet, + #[cfg(feature = "regtest")] + Regtest, +} + +impl ZcashNetwork { + fn to_network_type(&self) -> NetworkType { + match self { + Self::Mainnet => NetworkType::Main, + Self::Testnet => NetworkType::Test, + #[cfg(feature = "regtest")] + Self::Regtest => NetworkType::Regtest, + } + } + + fn to_network_parameters(&self) -> Network { + match self { + Self::Mainnet => Network::MainNetwork, + Self::Testnet => Network::TestNetwork, + #[cfg(feature = "regtest")] + Self::Regtest => Network::TestNetwork, + } + } + fn new(network: Network) -> Self { + match network { + Network::MainNetwork => Self::Mainnet, + Network::TestNetwork => Self::Testnet, + } + } + + fn new_from_network_type(network_type: NetworkType) -> Self { + match network_type { + NetworkType::Main => Self::Mainnet, + NetworkType::Test => Self::Testnet, + #[cfg(not(feature = "regtest"))] + NetworkType::Regtest => Self::Testnet, + #[cfg(feature = "regtest")] + NetworkType::Regtest => Self::Regtest, + } + } +} + +#[derive(uniffi::Error, thiserror::Error, Debug, Clone)] +pub enum OrchardKeyError { + #[error("Failed to derive Key with : {message:?}")] + KeyDerivationError { message: String }, + #[error("Failed to serialized key")] + SerializationError, + #[error("Failed to serialized key")] + DeserializationError, + #[error("Failed to sign message with error: {error_message:?}")] + OtherError { error_message: String }, +} + +/// This responds to Backup and DKG requirements +/// for FROST. +/// +/// - Note: See [FROST Book backup section](https://frost.zfnd.org/zcash/technical-details.html#backing-up-key-shares) +#[derive(uniffi::Object, Clone)] +pub struct OrchardKeyParts { + pub nk: Vec, + pub rivk: Vec, +} + +#[uniffi::export] +impl OrchardKeyParts { + + /// Creates a Random `nk` and `rivk` from a random Spending Key + /// originated from a random 24-word Mnemonic seed which is tossed + /// away. + /// This responds to Backup and DKG requirements + /// for FROST. + /// + /// - Note: See [FROST Book backup section](https://frost.zfnd.org/zcash/technical-details.html#backing-up-key-shares) + #[uniffi::constructor] + fn random(network: ZcashNetwork) -> Result, OrchardKeyError> { + let mnemonic = Mnemonic::::generate(bip0039::Count::Words24); + let random_entropy = mnemonic.entropy(); + let spending_key = + SpendingKey::from_zip32_seed(random_entropy, network.to_network_parameters().coin_type(), AccountId::ZERO) + .map_err(|e| OrchardKeyError::KeyDerivationError { + message: e.to_string(), + })?; + + let nk = NullifierDerivingKey::from(&spending_key); + let rivk = CommitIvkRandomness::from(&spending_key); + + Ok(Arc::new(OrchardKeyParts { + nk: nk.to_bytes().to_vec(), + rivk: rivk.to_bytes().to_vec(), + })) + } +} + + +/// An Zcash Orchard Address and its associated network type. +#[derive(uniffi::Object)] +pub struct OrchardAddress { + network: ZcashNetwork, + addr: Address, +} + +#[uniffi::export] +impl OrchardAddress { + /// Creates an [`OrchardAddress`] from its string-encoded form + /// If the string is invalid `Err(OrchardKeyError::DeserializationError)` + /// is returned in the Result. + #[uniffi::constructor] + pub fn new_from_string(string: String) -> Result, OrchardKeyError> { + let (network, addr) = zcash_address::unified::Address::decode(&string) + .map_err(|_| OrchardKeyError::DeserializationError)?; + + Ok(Arc::new(OrchardAddress { + network: ZcashNetwork::new_from_network_type(network), + addr, + })) + } + + /// Returns the string-encoded form of this Orchard Address (A + /// Unified Address containing only the orchard receiver.) + pub fn string_encoded(&self) -> String { + self.addr.encode(&self.network.to_network_type()) + } +} + +/// A UnifiedViewingKey containing only an Orchard component and +/// its associated network constant. +#[derive(uniffi::Object, Clone)] +pub struct OrchardFullViewingKey { + network: ZcashNetwork, + fvk: FullViewingKey, +} +#[uniffi::export] +impl OrchardFullViewingKey { + /// Creates a new FullViewingKey from a ZIP-32 Seed and validating key + /// using the `Network` coin type on `AccountId(0u32)` + /// see https://frost.zfnd.org/zcash/technical-details.html for more + /// information. + #[uniffi::constructor] + pub fn new_from_validating_key_and_seed( + validating_key: &OrchardSpendValidatingKey, + zip_32_seed: Vec, + network: ZcashNetwork, + ) -> Result, OrchardKeyError> { + let network = network.to_network_parameters(); + let sk = SpendingKey::from_zip32_seed( + &zip_32_seed, + network.coin_type(), + AccountId::try_from(0).map_err(|e| OrchardKeyError::KeyDerivationError { + message: e.to_string(), + })?, + ) + .map_err(|e| OrchardKeyError::KeyDerivationError { + message: e.to_string(), + })?; + + // derive the FVK from the random spending key. + let random_fvk = FullViewingKey::from(&sk); + // get its bytes + let mut fvk_bytes = random_fvk.to_bytes(); + // get bytes from provided `ak` + let ak_bytes = validating_key.key.to_bytes(); + + // now we will replace the raw bytes of the current ak with the + // ones generated with FROST. This is not elegant but will do + // for now. + fvk_bytes[0..32].copy_from_slice(&ak_bytes); + + // now we will construct the viewing key from it + let frosty_fvk = FullViewingKey::from_bytes(&fvk_bytes); + + match frosty_fvk { + Some(f) => Ok(Arc::new(OrchardFullViewingKey { + network: ZcashNetwork::new(network), + fvk: f, + })), + None => Err(OrchardKeyError::KeyDerivationError { + message: "could not derive FROST fvk from resulting bytes".to_string(), + }), + } + } + + /// Creates an [`OrchardFullViewingKey`] from its checked composing parts + /// and its associated Network constant. + #[uniffi::constructor] + pub fn new_from_checked_parts( + ak: Arc, + nk: Arc, + rivk: Arc, + network: ZcashNetwork, + ) -> Result, OrchardKeyError> { + let ufvk = + Self::new_from_parts(&ak.key, &nk.nk, &rivk.rivk, network.to_network_parameters())?; + + Ok(Arc::new(ufvk)) + } + + /// Decodes a [`OrchardFullViewingKey`] from its Unified Full Viewing Key + /// string-encoded format. If this operation fails, it returns + /// `Err(OrchardKeyError::DeserializationError)` + #[uniffi::constructor] + pub fn decode( + string_enconded: String, + network: ZcashNetwork, + ) -> Result, OrchardKeyError> { + let ufvk = + UnifiedFullViewingKey::decode(&network.to_network_parameters(), &string_enconded) + .map_err(|_| OrchardKeyError::DeserializationError)?; + + match ufvk.orchard() { + Some(viewing_key) => { + let orchard_vk = OrchardFullViewingKey { + fvk: viewing_key.clone(), + network, + }; + Ok(Arc::new(orchard_vk)) + } + None => Err(OrchardKeyError::KeyDerivationError { + message: "No Orchard key on Unified Viewing key".to_string(), + }), + } + } + + /// Encodes a [`OrchardFullViewingKey`] to its Unified Full Viewing Key + /// string-encoded format. If this operation fails, it returns + /// `Err(OrchardKeyError::DeserializationError)`. This should be straight + /// forward and an error thrown could indicate another kind of issue like a + /// PEBKAC. + fn encode(&self) -> Result { + let ufvk = UnifiedFullViewingKey::from_orchard_fvk( + self.fvk.clone() + ) + .map_err(|e| OrchardKeyError::KeyDerivationError { + message: e.to_string(), + })?; + + Ok(ufvk.encode(&self.network.to_network_parameters())) + } + + /// derives external address 0 of this Orchard Full viewing key. + fn derive_address(&self) -> Result, OrchardKeyError> { + let s = self.fvk.address_at(0u64, Scope::External); + + let orchard_receiver = Receiver::Orchard(s.to_raw_address_bytes()); + + let ua = zcash_address::unified::Address::try_from_items(vec![orchard_receiver]) + .map_err(|_| OrchardKeyError::SerializationError)?; + + Ok(Arc::new(OrchardAddress { + network: self.network.clone(), + addr: ua, + })) + } + + // Returns the [`OrchardNullifierDerivingKey`] component of this FVK + pub fn nk(&self) -> Arc { + let nk = OrchardNullifierDerivingKey { + nk: *self.fvk.nk() + }; + + Arc::new(nk) + } + + /// Returns the External Scope of this FVK + pub fn rivk(&self) -> Arc { + let rivk = OrchardCommitIvkRandomness { + rivk: self.fvk.rivk(Scope::External) + }; + + Arc::new(rivk) + } + + /// Returns the Spend Validating Key component of this Orchard FVK + pub fn ak(&self) -> Arc { + let ak = OrchardSpendValidatingKey { + key: self.fvk.ak().clone() + }; + + Arc::new(ak) + } +} + +impl OrchardFullViewingKey { + /// Creates an [`OrchardFullViewingKey`] from its composing parts. + /// + /// - Note: See [FROST Book backup section](https://frost.zfnd.org/zcash/technical-details.html#backing-up-key-shares) + fn new_from_parts( + ak: &SpendValidatingKey, + nk: &NullifierDerivingKey, + rivk: &CommitIvkRandomness, + network: Network, + ) -> Result { + let fvk = FullViewingKey::from_checked_parts(ak.clone(), *nk, *rivk); + + Ok(OrchardFullViewingKey { + network: ZcashNetwork::new(network), + fvk, + }) + } +} + +/// The `ak` component of an Orchard Full Viewing key. This shall be +/// derived from the Spend Authorizing Key `ask` +#[derive(uniffi::Object)] +pub struct OrchardSpendValidatingKey { + key: SpendValidatingKey, +} + +#[uniffi::export] +impl OrchardSpendValidatingKey { + /// Deserialized the [`OrchardSpendValidatingKey`] into bytes for + /// backup purposes. + /// - Note: See [ZF FROST Book - Technical Details](https://frost.zfnd.org/zcash/technical-details.html) + /// to serialize use the `OrchardSpendValidatingKey::to_bytes` + /// constructor + #[uniffi::constructor] + pub fn from_bytes(bytes: Vec) -> Result, OrchardKeyError> { + match SpendValidatingKey::from_bytes(&bytes) { + Some(ak) => Ok(Arc::new(OrchardSpendValidatingKey { key: ak })), + None => Err(OrchardKeyError::DeserializationError), + } + } + + /// Serialized the [`OrchardSpendValidatingKey`] into bytes for + /// backup purposes. + /// - Note: See [ZF FROST Book - Technical Details](https://frost.zfnd.org/zcash/technical-details.html) + /// to deserialize use the `OrchardSpendValidatingKey::from_bytes` + /// constructor + pub fn to_bytes(&self) -> Vec { + self.key.to_bytes().to_vec() + } +} + + +/// The Orchard Nullifier Deriving Key component of an +/// Orchard full viewing key. This is intended for key backup +/// purposes. +/// - Note: See [ZF FROST Book - Technical Details](https://frost.zfnd.org/zcash/technical-details.html) +#[derive(uniffi::Object)] +pub struct OrchardNullifierDerivingKey { + nk: NullifierDerivingKey, +} + +#[uniffi::export] +impl OrchardNullifierDerivingKey { + /// Creates an [`OrchardNullifierDerivingKey`] from a sequence of bytes. + /// If the byte sequence is not suitable for doing so, it will return an + /// [`Err(OrchardKeyError::DeserializationError)`] + #[uniffi::constructor] + fn new(bytes: Vec) -> Result, OrchardKeyError> { + match NullifierDerivingKey::from_bytes(&bytes) { + Some(nk) => Ok(Arc::new(OrchardNullifierDerivingKey { nk })), + None => Err(OrchardKeyError::DeserializationError), + } + } + + /// Serializes [`OrchardNullifierDerivingKey`] to a sequence of bytes. + pub fn to_bytes(&self) -> Vec { + self.nk.to_bytes().to_vec() + } +} + +/// The `rivk` component of an Orchard Full Viewing Key. +/// This is intended for key backup purposes. +///- Note: See [ZF FROST Book - Technical Details](https://frost.zfnd.org/zcash/technical-details.html) +#[derive(uniffi::Object, Clone)] +pub struct OrchardCommitIvkRandomness { + rivk: CommitIvkRandomness, +} + +#[uniffi::export] +impl OrchardCommitIvkRandomness { + #[uniffi::constructor] + /// Creates a `rivk` from a sequence of bytes. Returns [`OrchardKeyError::DeserializationError`] + /// if these bytes can't be deserialized into a valid `rivk` + pub fn new(bytes: Vec) -> Result, OrchardKeyError> { + match CommitIvkRandomness::from_bytes(&bytes) { + Some(rivk) => Ok(Arc::new(OrchardCommitIvkRandomness { rivk })), + None => Err(OrchardKeyError::DeserializationError), + } + } + + pub fn to_bytes(&self) -> Vec { + self.rivk.to_bytes().to_vec() + } +} + +#[cfg(test)] +mod tests { + use zcash_address::unified::{Encoding, Receiver}; + use zip32::Scope; + + use crate::orchard::ZcashNetwork; + + use super::{OrchardFullViewingKey, OrchardSpendValidatingKey}; + + /// this verifying key is from the "FROST Book" + /// https://frost.zfnd.org/zcash/ywallet-demo.html + #[test] + fn test_ak_generates_spend_validating_key() { + let verifying_hex_string = + "d2bf40ca860fb97e9d6d15d7d25e4f17d2e8ba5dd7069188cbf30b023910a71b"; + let hex_bytes = hex::decode(verifying_hex_string).unwrap(); + + assert!(OrchardSpendValidatingKey::from_bytes(hex_bytes).is_ok()) + } + + /// this verifying key is from the "FROST Book" + /// https://frost.zfnd.org/zcash/ywallet-demo.html + /// seed was generated with https://iancoleman.io/bip39/ + /// don't use it yourself. Don't even think about it! + #[test] + fn test_ak_and_seed_creates_a_valid_viewing_key() { + let verifying_hex_string = + "d2bf40ca860fb97e9d6d15d7d25e4f17d2e8ba5dd7069188cbf30b023910a71b"; + let hex_bytes = hex::decode(verifying_hex_string).unwrap(); + + let verifying_key = OrchardSpendValidatingKey::from_bytes(hex_bytes).unwrap(); + + let random_seed_bytes = hex::decode("659ce2e5362b515f30c38807942a10c18a3a2f7584e7135b3523d5e72bb796cc64c366a8a6bfb54a5b32c41720bdb135758c1afacac3e72fd5974be0846bf7a5").unwrap(); + + let orchard_fvk = OrchardFullViewingKey::new_from_validating_key_and_seed( + &*verifying_key, + random_seed_bytes, + ZcashNetwork::new(zcash_protocol::consensus::Network::TestNetwork), + ); + + let s = orchard_fvk + .clone() + .unwrap() + .fvk + .address_at(0u64, Scope::External); + + let orchard_receiver = Receiver::Orchard(s.to_raw_address_bytes()); + + let ua = zcash_address::unified::Address::try_from_items(vec![orchard_receiver]); + + assert!(ua.is_ok()); + match orchard_fvk { + Ok(_) => assert!(true), + Err(e) => panic!("failed with error {:?}", e), + } + } +} diff --git a/frost-uniffi-sdk/src/orchard/lib.rs b/frost-uniffi-sdk/src/orchard/lib.rs new file mode 100644 index 0000000..e310dbd --- /dev/null +++ b/frost-uniffi-sdk/src/orchard/lib.rs @@ -0,0 +1,3 @@ +pub mod keys; + +uniffi::setup_scaffolding!(); diff --git a/frost-uniffi-sdk/src/orchard/mod.rs b/frost-uniffi-sdk/src/orchard/mod.rs new file mode 100644 index 0000000..cf0e474 --- /dev/null +++ b/frost-uniffi-sdk/src/orchard/mod.rs @@ -0,0 +1,2 @@ +mod keys; +pub use self::keys::*; \ No newline at end of file diff --git a/frost-uniffi-sdk/tests/helpers.rs b/frost-uniffi-sdk/tests/helpers.rs index 828f2f7..8594dd4 100644 --- a/frost-uniffi-sdk/tests/helpers.rs +++ b/frost-uniffi-sdk/tests/helpers.rs @@ -34,6 +34,7 @@ pub fn key_package( key_packages } +#[cfg(test)] pub fn round_1( mut rng: &mut ThreadRng, key_packages: &HashMap, diff --git a/frost-uniffi-sdk/tests/integration_tests.rs b/frost-uniffi-sdk/tests/integration_tests.rs index 98b0a60..722c1b5 100644 --- a/frost-uniffi-sdk/tests/integration_tests.rs +++ b/frost-uniffi-sdk/tests/integration_tests.rs @@ -1,3 +1,4 @@ +#[cfg(test)] mod helpers; use frost_uniffi_sdk::{ @@ -13,7 +14,7 @@ use frost_uniffi_sdk::coordinator::aggregate; #[cfg(not(feature = "redpallas"))] use helpers::round_2; - +#[cfg(not(feature = "redpallas"))] type E = frost_ed25519::Ed25519Sha512; #[cfg(not(feature = "redpallas"))] #[test] diff --git a/frost-uniffi-sdk/tests/randomized_integration_tests.rs b/frost-uniffi-sdk/tests/randomized_integration_tests.rs index 435aaae..67415e0 100644 --- a/frost-uniffi-sdk/tests/randomized_integration_tests.rs +++ b/frost-uniffi-sdk/tests/randomized_integration_tests.rs @@ -92,7 +92,7 @@ fn test_randomized_trusted_from_configuration_with_secret() { &frost_randomizer, ) .unwrap(); - + signature_shares.insert(participant_identifier.clone(), signature_share); } diff --git a/frost_go_ffi/frost_go_ffi.h b/frost_go_ffi/frost_go_ffi.h index 96ef670..a734780 100644 --- a/frost_go_ffi/frost_go_ffi.h +++ b/frost_go_ffi/frost_go_ffi.h @@ -88,10 +88,147 @@ void uniffi_frost_uniffi_sdk_fn_free_dkground2secretpackage( RustCallStatus* out_status ); +void uniffi_frost_uniffi_sdk_fn_free_frostrandomizedparams( + void* ptr, + RustCallStatus* out_status +); + +void uniffi_frost_uniffi_sdk_fn_free_orchardaddress( + void* ptr, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_constructor_orchardaddress_new_from_string( + RustBuffer string, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_method_orchardaddress_string_encoded( + void* ptr, + RustCallStatus* out_status +); + +void uniffi_frost_uniffi_sdk_fn_free_orchardcommitivkrandomness( + void* ptr, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_constructor_orchardcommitivkrandomness_new( + RustBuffer bytes, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_method_orchardcommitivkrandomness_to_bytes( + void* ptr, + RustCallStatus* out_status +); + +void uniffi_frost_uniffi_sdk_fn_free_orchardfullviewingkey( + void* ptr, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_constructor_orchardfullviewingkey_decode( + RustBuffer string_enconded, + RustBuffer network, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_constructor_orchardfullviewingkey_new_from_checked_parts( + void* ak, + void* nk, + void* rivk, + RustBuffer network, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_constructor_orchardfullviewingkey_new_from_validating_key_and_seed( + void* validating_key, + RustBuffer zip_32_seed, + RustBuffer network, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_ak( + void* ptr, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_derive_address( + void* ptr, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_encode( + void* ptr, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_nk( + void* ptr, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_rivk( + void* ptr, + RustCallStatus* out_status +); + +void uniffi_frost_uniffi_sdk_fn_free_orchardkeyparts( + void* ptr, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_constructor_orchardkeyparts_random( + RustBuffer network, + RustCallStatus* out_status +); + +void uniffi_frost_uniffi_sdk_fn_free_orchardnullifierderivingkey( + void* ptr, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_constructor_orchardnullifierderivingkey_new( + RustBuffer bytes, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_method_orchardnullifierderivingkey_to_bytes( + void* ptr, + RustCallStatus* out_status +); + +void uniffi_frost_uniffi_sdk_fn_free_orchardspendvalidatingkey( + void* ptr, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_constructor_orchardspendvalidatingkey_from_bytes( + RustBuffer bytes, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_method_orchardspendvalidatingkey_to_bytes( + void* ptr, + RustCallStatus* out_status +); + RustBuffer uniffi_frost_uniffi_sdk_fn_func_aggregate( RustBuffer signing_package, RustBuffer signature_shares, RustBuffer pubkey_package, + RustBuffer randomizer, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_func_commitment_to_json( + RustBuffer commitment, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_func_from_hex_string( + RustBuffer hex_string, RustCallStatus* out_status ); @@ -115,6 +252,38 @@ RustBuffer uniffi_frost_uniffi_sdk_fn_func_identifier_from_uint16( RustCallStatus* out_status ); +RustBuffer uniffi_frost_uniffi_sdk_fn_func_json_to_commitment( + RustBuffer commitment_json, + RustBuffer identifier, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_func_json_to_key_package( + RustBuffer key_package_json, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_func_json_to_public_key_package( + RustBuffer public_key_package_json, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_func_json_to_randomizer( + RustBuffer randomizer_json, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_func_json_to_signature_share( + RustBuffer signature_share_json, + RustBuffer identifier, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_func_key_package_to_json( + RustBuffer key_package, + RustCallStatus* out_status +); + RustBuffer uniffi_frost_uniffi_sdk_fn_func_new_signing_package( RustBuffer message, RustBuffer commitments, @@ -141,10 +310,37 @@ RustBuffer uniffi_frost_uniffi_sdk_fn_func_part_3( RustCallStatus* out_status ); +RustBuffer uniffi_frost_uniffi_sdk_fn_func_public_key_package_to_json( + RustBuffer public_key_package, + RustCallStatus* out_status +); + +void* uniffi_frost_uniffi_sdk_fn_func_randomized_params_from_public_key_and_signing_package( + RustBuffer public_key, + RustBuffer signing_package, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_func_randomizer_from_params( + void* randomized_params, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_func_randomizer_to_json( + RustBuffer randomizer, + RustCallStatus* out_status +); + RustBuffer uniffi_frost_uniffi_sdk_fn_func_sign( RustBuffer signing_package, RustBuffer nonces, RustBuffer key_package, + RustBuffer randomizer, + RustCallStatus* out_status +); + +RustBuffer uniffi_frost_uniffi_sdk_fn_func_signature_share_package_to_json( + RustBuffer signature_share, RustCallStatus* out_status ); @@ -169,6 +365,14 @@ RustBuffer uniffi_frost_uniffi_sdk_fn_func_verify_and_get_key_package_from( RustCallStatus* out_status ); +void uniffi_frost_uniffi_sdk_fn_func_verify_randomized_signature( + RustBuffer randomizer, + RustBuffer message, + RustBuffer signature, + RustBuffer pubkey, + RustCallStatus* out_status +); + void uniffi_frost_uniffi_sdk_fn_func_verify_signature( RustBuffer message, RustBuffer signature, @@ -479,6 +683,14 @@ uint16_t uniffi_frost_uniffi_sdk_checksum_func_aggregate( RustCallStatus* out_status ); +uint16_t uniffi_frost_uniffi_sdk_checksum_func_commitment_to_json( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_func_from_hex_string( + RustCallStatus* out_status +); + uint16_t uniffi_frost_uniffi_sdk_checksum_func_generate_nonces_and_commitments( RustCallStatus* out_status ); @@ -495,6 +707,30 @@ uint16_t uniffi_frost_uniffi_sdk_checksum_func_identifier_from_uint16( RustCallStatus* out_status ); +uint16_t uniffi_frost_uniffi_sdk_checksum_func_json_to_commitment( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_func_json_to_key_package( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_func_json_to_public_key_package( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_func_json_to_randomizer( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_func_json_to_signature_share( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_func_key_package_to_json( + RustCallStatus* out_status +); + uint16_t uniffi_frost_uniffi_sdk_checksum_func_new_signing_package( RustCallStatus* out_status ); @@ -511,10 +747,30 @@ uint16_t uniffi_frost_uniffi_sdk_checksum_func_part_3( RustCallStatus* out_status ); +uint16_t uniffi_frost_uniffi_sdk_checksum_func_public_key_package_to_json( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_func_randomized_params_from_public_key_and_signing_package( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_func_randomizer_from_params( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_func_randomizer_to_json( + RustCallStatus* out_status +); + uint16_t uniffi_frost_uniffi_sdk_checksum_func_sign( RustCallStatus* out_status ); +uint16_t uniffi_frost_uniffi_sdk_checksum_func_signature_share_package_to_json( + RustCallStatus* out_status +); + uint16_t uniffi_frost_uniffi_sdk_checksum_func_trusted_dealer_keygen_from( RustCallStatus* out_status ); @@ -531,10 +787,82 @@ uint16_t uniffi_frost_uniffi_sdk_checksum_func_verify_and_get_key_package_from( RustCallStatus* out_status ); +uint16_t uniffi_frost_uniffi_sdk_checksum_func_verify_randomized_signature( + RustCallStatus* out_status +); + uint16_t uniffi_frost_uniffi_sdk_checksum_func_verify_signature( RustCallStatus* out_status ); +uint16_t uniffi_frost_uniffi_sdk_checksum_method_orchardaddress_string_encoded( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_method_orchardcommitivkrandomness_to_bytes( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_ak( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_derive_address( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_encode( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_nk( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_rivk( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_method_orchardnullifierderivingkey_to_bytes( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_method_orchardspendvalidatingkey_to_bytes( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_constructor_orchardaddress_new_from_string( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_constructor_orchardcommitivkrandomness_new( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_decode( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_new_from_checked_parts( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_new_from_validating_key_and_seed( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_constructor_orchardkeyparts_random( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_constructor_orchardnullifierderivingkey_new( + RustCallStatus* out_status +); + +uint16_t uniffi_frost_uniffi_sdk_checksum_constructor_orchardspendvalidatingkey_from_bytes( + RustCallStatus* out_status +); + uint32_t ffi_frost_uniffi_sdk_uniffi_contract_version( RustCallStatus* out_status ); diff --git a/frost_go_ffi/frost_go_ffi_orchard_keys_test.go b/frost_go_ffi/frost_go_ffi_orchard_keys_test.go new file mode 100644 index 0000000..95ade7c --- /dev/null +++ b/frost_go_ffi/frost_go_ffi_orchard_keys_test.go @@ -0,0 +1,89 @@ +package frost_uniffi_sdk + +import ( + "encoding/hex" + "testing" +) + +func TestUFVKAndAddressAreDerivedFromSeed(t *testing.T) { + // Define the expected values + expectedFVK := "uviewtest1jd7ucm0fdh9s0gqk9cse9xtqcyycj2k06krm3l9r6snakdzqz5tdp3ua4nerj8uttfepzjxrhp9a4c3wl7h508fmjwqgmqgvslcgvc8htqzm8gg5h9sygqt76un40xvzyyk7fvlestphmmz9emyqhjkl60u4dx25t86lhs30jreghq40cfnw9nqh858z4" + expectedAddress := "utest1fqasmz9zpaq3qlg4ghy6r5cf6u3qsvdrty9q6e4jh4sxd2ztryy0nvp59jpu5npaqwrgf7sgqu9z7hz9sdxw22vdpay4v4mm8vv2hlg4" + + // Hex-encoded strings + hexStringAk := "d2bf40ca860fb97e9d6d15d7d25e4f17d2e8ba5dd7069188cbf30b023910a71b" + hexAk, err := hex.DecodeString(hexStringAk) + if err != nil { + t.Fatalf("failed to decode hex string for Ak: %v", err) + } + + randomSeedBytesHexString := "659ce2e5362b515f30c38807942a10c18a3a2f7584e7135b3523d5e72bb796cc64c366a8a6bfb54a5b32c41720bdb135758c1afacac3e72fd5974be0846bf7a5" + randomSeedBytes, err := hex.DecodeString(randomSeedBytesHexString) + if err != nil { + t.Fatalf("failed to decode hex string for random seed: %v", err) + } + + zcashNetwork := ZcashNetworkTestnet + + ak, err := OrchardSpendValidatingKeyFromBytes(hexAk) + if err != nil { + t.Fatalf("failed to create OrchardSpendValidatingKey: %v", err) + } + + fvk, err := OrchardFullViewingKeyNewFromValidatingKeyAndSeed(ak, randomSeedBytes, zcashNetwork) + if err != nil { + t.Fatalf("failed to create OrchardFullViewingKey: %v", err) + } + + encodedFVK, err := fvk.Encode() + if err != nil { + t.Fatalf("failed to create encode OrchardFullViewingKey: %v", err) + } + + if encodedFVK != expectedFVK { + t.Errorf("expected FVK %s, got %s", expectedFVK, encodedFVK) + } + + address, err := fvk.DeriveAddress() + if err != nil { + t.Fatalf("failed to derive address: %v", err) + } + stringEncodedAddress := address.StringEncoded() + if stringEncodedAddress != expectedAddress { + t.Errorf("expected address %s, got %s", expectedAddress, stringEncodedAddress) + } +} + +func TestUFVKIsDecomposedOnParts(t *testing.T) { + // Define the UFVK string to be tested + ufvkString := "uviewtest1jd7ucm0fdh9s0gqk9cse9xtqcyycj2k06krm3l9r6snakdzqz5tdp3ua4nerj8uttfepzjxrhp9a4c3wl7h508fmjwqgmqgvslcgvc8htqzm8gg5h9sygqt76un40xvzyyk7fvlestphmmz9emyqhjkl60u4dx25t86lhs30jreghq40cfnw9nqh858z4" + // Decode the UFVK string + zcashNetwork := ZcashNetworkTestnet + ufvk, err := OrchardFullViewingKeyDecode(ufvkString, zcashNetwork) + + if err != nil { + t.Fatalf("failed to decode UFVK: %v", err) + } + + // Decompose UFVK into parts + nk := ufvk.Nk() + + ak := ufvk.Ak() + + rivk := ufvk.Rivk() + + // Reconstruct the UFVK from the decomposed parts + roundtripUFVK, err := OrchardFullViewingKeyNewFromCheckedParts(ak, nk, rivk, zcashNetwork) + if err != nil { + t.Fatalf("failed to reconstruct UFVK from parts: %v", err) + } + + roundtripUFVKEncoded, err := roundtripUFVK.Encode() + if err != nil { + t.Fatalf("failed to decode Roundtrip UFVK: %v", err) + } + // Verify that the original UFVK and the round-trip UFVK are equal + if roundtripUFVKEncoded != ufvkString { + t.Errorf("UFVK mismatch: expected %v, got %v", ufvk, roundtripUFVK) + } +} diff --git a/frost_go_ffi/frost_uniffi_sdk.go b/frost_go_ffi/frost_uniffi_sdk.go index 935b785..3c5002d 100644 --- a/frost_go_ffi/frost_uniffi_sdk.go +++ b/frost_go_ffi/frost_uniffi_sdk.go @@ -348,11 +348,29 @@ func uniffiCheckChecksums() { checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_frost_uniffi_sdk_checksum_func_aggregate(uniffiStatus) }) - if checksum != 46119 { + if checksum != 3424 { // If this happens try cleaning and rebuilding your project panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_aggregate: UniFFI API checksum mismatch") } } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_commitment_to_json(uniffiStatus) + }) + if checksum != 12818 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_commitment_to_json: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_from_hex_string(uniffiStatus) + }) + if checksum != 29801 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_from_hex_string: UniFFI API checksum mismatch") + } + } { checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_frost_uniffi_sdk_checksum_func_generate_nonces_and_commitments(uniffiStatus) @@ -389,6 +407,60 @@ func uniffiCheckChecksums() { panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_identifier_from_uint16: UniFFI API checksum mismatch") } } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_json_to_commitment(uniffiStatus) + }) + if checksum != 62453 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_json_to_commitment: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_json_to_key_package(uniffiStatus) + }) + if checksum != 58769 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_json_to_key_package: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_json_to_public_key_package(uniffiStatus) + }) + if checksum != 8036 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_json_to_public_key_package: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_json_to_randomizer(uniffiStatus) + }) + if checksum != 47111 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_json_to_randomizer: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_json_to_signature_share(uniffiStatus) + }) + if checksum != 62549 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_json_to_signature_share: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_key_package_to_json(uniffiStatus) + }) + if checksum != 11157 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_key_package_to_json: UniFFI API checksum mismatch") + } + } { checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_frost_uniffi_sdk_checksum_func_new_signing_package(uniffiStatus) @@ -425,15 +497,60 @@ func uniffiCheckChecksums() { panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_part_3: UniFFI API checksum mismatch") } } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_public_key_package_to_json(uniffiStatus) + }) + if checksum != 20437 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_public_key_package_to_json: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_randomized_params_from_public_key_and_signing_package(uniffiStatus) + }) + if checksum != 58556 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_randomized_params_from_public_key_and_signing_package: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_randomizer_from_params(uniffiStatus) + }) + if checksum != 50217 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_randomizer_from_params: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_randomizer_to_json(uniffiStatus) + }) + if checksum != 23719 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_randomizer_to_json: UniFFI API checksum mismatch") + } + } { checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_frost_uniffi_sdk_checksum_func_sign(uniffiStatus) }) - if checksum != 48101 { + if checksum != 723 { // If this happens try cleaning and rebuilding your project panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_sign: UniFFI API checksum mismatch") } } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_signature_share_package_to_json(uniffiStatus) + }) + if checksum != 2249 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_signature_share_package_to_json: UniFFI API checksum mismatch") + } + } { checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_frost_uniffi_sdk_checksum_func_trusted_dealer_keygen_from(uniffiStatus) @@ -470,6 +587,15 @@ func uniffiCheckChecksums() { panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_verify_and_get_key_package_from: UniFFI API checksum mismatch") } } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_func_verify_randomized_signature(uniffiStatus) + }) + if checksum != 24114 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_verify_randomized_signature: UniFFI API checksum mismatch") + } + } { checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_frost_uniffi_sdk_checksum_func_verify_signature(uniffiStatus) @@ -479,6 +605,159 @@ func uniffiCheckChecksums() { panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_func_verify_signature: UniFFI API checksum mismatch") } } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_method_orchardaddress_string_encoded(uniffiStatus) + }) + if checksum != 38758 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_method_orchardaddress_string_encoded: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_method_orchardcommitivkrandomness_to_bytes(uniffiStatus) + }) + if checksum != 54004 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_method_orchardcommitivkrandomness_to_bytes: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_ak(uniffiStatus) + }) + if checksum != 1900 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_ak: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_derive_address(uniffiStatus) + }) + if checksum != 26015 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_derive_address: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_encode(uniffiStatus) + }) + if checksum != 34271 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_encode: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_nk(uniffiStatus) + }) + if checksum != 33472 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_nk: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_rivk(uniffiStatus) + }) + if checksum != 25054 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_method_orchardfullviewingkey_rivk: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_method_orchardnullifierderivingkey_to_bytes(uniffiStatus) + }) + if checksum != 8783 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_method_orchardnullifierderivingkey_to_bytes: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_method_orchardspendvalidatingkey_to_bytes(uniffiStatus) + }) + if checksum != 10051 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_method_orchardspendvalidatingkey_to_bytes: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_constructor_orchardaddress_new_from_string(uniffiStatus) + }) + if checksum != 64287 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_constructor_orchardaddress_new_from_string: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_constructor_orchardcommitivkrandomness_new(uniffiStatus) + }) + if checksum != 55160 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_constructor_orchardcommitivkrandomness_new: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_decode(uniffiStatus) + }) + if checksum != 6758 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_decode: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_new_from_checked_parts(uniffiStatus) + }) + if checksum != 19481 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_new_from_checked_parts: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_new_from_validating_key_and_seed(uniffiStatus) + }) + if checksum != 62836 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_constructor_orchardfullviewingkey_new_from_validating_key_and_seed: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_constructor_orchardkeyparts_random(uniffiStatus) + }) + if checksum != 3046 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_constructor_orchardkeyparts_random: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_constructor_orchardnullifierderivingkey_new(uniffiStatus) + }) + if checksum != 15347 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_constructor_orchardnullifierderivingkey_new: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_frost_uniffi_sdk_checksum_constructor_orchardspendvalidatingkey_from_bytes(uniffiStatus) + }) + if checksum != 63121 { + // If this happens try cleaning and rebuilding your project + panic("frost_uniffi_sdk: uniffi_frost_uniffi_sdk_checksum_constructor_orchardspendvalidatingkey_from_bytes: UniFFI API checksum mismatch") + } + } } type FfiConverterUint16 struct{} @@ -846,77 +1125,602 @@ func (_ FfiDestroyerDkgRound2SecretPackage) Destroy(value *DkgRound2SecretPackag value.Destroy() } -type Configuration struct { - MinSigners uint16 - MaxSigners uint16 - Secret []byte +type FrostRandomizedParams struct { + ffiObject FfiObject } -func (r *Configuration) Destroy() { - FfiDestroyerUint16{}.Destroy(r.MinSigners) - FfiDestroyerUint16{}.Destroy(r.MaxSigners) - FfiDestroyerBytes{}.Destroy(r.Secret) +func (object *FrostRandomizedParams) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() } -type FfiConverterTypeConfiguration struct{} +type FfiConverterFrostRandomizedParams struct{} -var FfiConverterTypeConfigurationINSTANCE = FfiConverterTypeConfiguration{} +var FfiConverterFrostRandomizedParamsINSTANCE = FfiConverterFrostRandomizedParams{} -func (c FfiConverterTypeConfiguration) Lift(rb RustBufferI) Configuration { - return LiftFromRustBuffer[Configuration](c, rb) +func (c FfiConverterFrostRandomizedParams) Lift(pointer unsafe.Pointer) *FrostRandomizedParams { + result := &FrostRandomizedParams{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_frost_uniffi_sdk_fn_free_frostrandomizedparams(pointer, status) + }), + } + runtime.SetFinalizer(result, (*FrostRandomizedParams).Destroy) + return result } -func (c FfiConverterTypeConfiguration) Read(reader io.Reader) Configuration { - return Configuration{ - FfiConverterUint16INSTANCE.Read(reader), - FfiConverterUint16INSTANCE.Read(reader), - FfiConverterBytesINSTANCE.Read(reader), - } +func (c FfiConverterFrostRandomizedParams) Read(reader io.Reader) *FrostRandomizedParams { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) } -func (c FfiConverterTypeConfiguration) Lower(value Configuration) RustBuffer { - return LowerIntoRustBuffer[Configuration](c, value) +func (c FfiConverterFrostRandomizedParams) Lower(value *FrostRandomizedParams) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*FrostRandomizedParams") + defer value.ffiObject.decrementPointer() + return pointer } -func (c FfiConverterTypeConfiguration) Write(writer io.Writer, value Configuration) { - FfiConverterUint16INSTANCE.Write(writer, value.MinSigners) - FfiConverterUint16INSTANCE.Write(writer, value.MaxSigners) - FfiConverterBytesINSTANCE.Write(writer, value.Secret) +func (c FfiConverterFrostRandomizedParams) Write(writer io.Writer, value *FrostRandomizedParams) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) } -type FfiDestroyerTypeConfiguration struct{} +type FfiDestroyerFrostRandomizedParams struct{} -func (_ FfiDestroyerTypeConfiguration) Destroy(value Configuration) { +func (_ FfiDestroyerFrostRandomizedParams) Destroy(value *FrostRandomizedParams) { value.Destroy() } -type DkgPart3Result struct { - PublicKeyPackage FrostPublicKeyPackage - KeyPackage FrostKeyPackage +type OrchardAddress struct { + ffiObject FfiObject } -func (r *DkgPart3Result) Destroy() { - FfiDestroyerTypeFrostPublicKeyPackage{}.Destroy(r.PublicKeyPackage) - FfiDestroyerTypeFrostKeyPackage{}.Destroy(r.KeyPackage) +func OrchardAddressNewFromString(string string) (*OrchardAddress, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeOrchardKeyError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_constructor_orchardaddress_new_from_string(FfiConverterStringINSTANCE.Lower(string), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *OrchardAddress + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterOrchardAddressINSTANCE.Lift(_uniffiRV), _uniffiErr + } } -type FfiConverterTypeDKGPart3Result struct{} - -var FfiConverterTypeDKGPart3ResultINSTANCE = FfiConverterTypeDKGPart3Result{} - -func (c FfiConverterTypeDKGPart3Result) Lift(rb RustBufferI) DkgPart3Result { - return LiftFromRustBuffer[DkgPart3Result](c, rb) +func (_self *OrchardAddress) StringEncoded() string { + _pointer := _self.ffiObject.incrementPointer("*OrchardAddress") + defer _self.ffiObject.decrementPointer() + return FfiConverterStringINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_method_orchardaddress_string_encoded( + _pointer, _uniffiStatus) + })) } -func (c FfiConverterTypeDKGPart3Result) Read(reader io.Reader) DkgPart3Result { - return DkgPart3Result{ - FfiConverterTypeFrostPublicKeyPackageINSTANCE.Read(reader), - FfiConverterTypeFrostKeyPackageINSTANCE.Read(reader), - } +func (object *OrchardAddress) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() } -func (c FfiConverterTypeDKGPart3Result) Lower(value DkgPart3Result) RustBuffer { - return LowerIntoRustBuffer[DkgPart3Result](c, value) +type FfiConverterOrchardAddress struct{} + +var FfiConverterOrchardAddressINSTANCE = FfiConverterOrchardAddress{} + +func (c FfiConverterOrchardAddress) Lift(pointer unsafe.Pointer) *OrchardAddress { + result := &OrchardAddress{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_frost_uniffi_sdk_fn_free_orchardaddress(pointer, status) + }), + } + runtime.SetFinalizer(result, (*OrchardAddress).Destroy) + return result +} + +func (c FfiConverterOrchardAddress) Read(reader io.Reader) *OrchardAddress { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterOrchardAddress) Lower(value *OrchardAddress) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*OrchardAddress") + defer value.ffiObject.decrementPointer() + return pointer +} + +func (c FfiConverterOrchardAddress) Write(writer io.Writer, value *OrchardAddress) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerOrchardAddress struct{} + +func (_ FfiDestroyerOrchardAddress) Destroy(value *OrchardAddress) { + value.Destroy() +} + +type OrchardCommitIvkRandomness struct { + ffiObject FfiObject +} + +func NewOrchardCommitIvkRandomness(bytes []byte) (*OrchardCommitIvkRandomness, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeOrchardKeyError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_constructor_orchardcommitivkrandomness_new(FfiConverterBytesINSTANCE.Lower(bytes), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *OrchardCommitIvkRandomness + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterOrchardCommitIvkRandomnessINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func (_self *OrchardCommitIvkRandomness) ToBytes() []byte { + _pointer := _self.ffiObject.incrementPointer("*OrchardCommitIvkRandomness") + defer _self.ffiObject.decrementPointer() + return FfiConverterBytesINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_method_orchardcommitivkrandomness_to_bytes( + _pointer, _uniffiStatus) + })) +} + +func (object *OrchardCommitIvkRandomness) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() +} + +type FfiConverterOrchardCommitIvkRandomness struct{} + +var FfiConverterOrchardCommitIvkRandomnessINSTANCE = FfiConverterOrchardCommitIvkRandomness{} + +func (c FfiConverterOrchardCommitIvkRandomness) Lift(pointer unsafe.Pointer) *OrchardCommitIvkRandomness { + result := &OrchardCommitIvkRandomness{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_frost_uniffi_sdk_fn_free_orchardcommitivkrandomness(pointer, status) + }), + } + runtime.SetFinalizer(result, (*OrchardCommitIvkRandomness).Destroy) + return result +} + +func (c FfiConverterOrchardCommitIvkRandomness) Read(reader io.Reader) *OrchardCommitIvkRandomness { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterOrchardCommitIvkRandomness) Lower(value *OrchardCommitIvkRandomness) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*OrchardCommitIvkRandomness") + defer value.ffiObject.decrementPointer() + return pointer +} + +func (c FfiConverterOrchardCommitIvkRandomness) Write(writer io.Writer, value *OrchardCommitIvkRandomness) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerOrchardCommitIvkRandomness struct{} + +func (_ FfiDestroyerOrchardCommitIvkRandomness) Destroy(value *OrchardCommitIvkRandomness) { + value.Destroy() +} + +type OrchardFullViewingKey struct { + ffiObject FfiObject +} + +func OrchardFullViewingKeyDecode(stringEnconded string, network ZcashNetwork) (*OrchardFullViewingKey, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeOrchardKeyError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_constructor_orchardfullviewingkey_decode(FfiConverterStringINSTANCE.Lower(stringEnconded), FfiConverterTypeZcashNetworkINSTANCE.Lower(network), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *OrchardFullViewingKey + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterOrchardFullViewingKeyINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func OrchardFullViewingKeyNewFromCheckedParts(ak *OrchardSpendValidatingKey, nk *OrchardNullifierDerivingKey, rivk *OrchardCommitIvkRandomness, network ZcashNetwork) (*OrchardFullViewingKey, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeOrchardKeyError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_constructor_orchardfullviewingkey_new_from_checked_parts(FfiConverterOrchardSpendValidatingKeyINSTANCE.Lower(ak), FfiConverterOrchardNullifierDerivingKeyINSTANCE.Lower(nk), FfiConverterOrchardCommitIvkRandomnessINSTANCE.Lower(rivk), FfiConverterTypeZcashNetworkINSTANCE.Lower(network), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *OrchardFullViewingKey + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterOrchardFullViewingKeyINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func OrchardFullViewingKeyNewFromValidatingKeyAndSeed(validatingKey *OrchardSpendValidatingKey, zip32Seed []byte, network ZcashNetwork) (*OrchardFullViewingKey, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeOrchardKeyError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_constructor_orchardfullviewingkey_new_from_validating_key_and_seed(FfiConverterOrchardSpendValidatingKeyINSTANCE.Lower(validatingKey), FfiConverterBytesINSTANCE.Lower(zip32Seed), FfiConverterTypeZcashNetworkINSTANCE.Lower(network), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *OrchardFullViewingKey + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterOrchardFullViewingKeyINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func (_self *OrchardFullViewingKey) Ak() *OrchardSpendValidatingKey { + _pointer := _self.ffiObject.incrementPointer("*OrchardFullViewingKey") + defer _self.ffiObject.decrementPointer() + return FfiConverterOrchardSpendValidatingKeyINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_ak( + _pointer, _uniffiStatus) + })) +} + +func (_self *OrchardFullViewingKey) DeriveAddress() (*OrchardAddress, error) { + _pointer := _self.ffiObject.incrementPointer("*OrchardFullViewingKey") + defer _self.ffiObject.decrementPointer() + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeOrchardKeyError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_derive_address( + _pointer, _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *OrchardAddress + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterOrchardAddressINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func (_self *OrchardFullViewingKey) Encode() (string, error) { + _pointer := _self.ffiObject.incrementPointer("*OrchardFullViewingKey") + defer _self.ffiObject.decrementPointer() + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeOrchardKeyError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_encode( + _pointer, _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue string + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterStringINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func (_self *OrchardFullViewingKey) Nk() *OrchardNullifierDerivingKey { + _pointer := _self.ffiObject.incrementPointer("*OrchardFullViewingKey") + defer _self.ffiObject.decrementPointer() + return FfiConverterOrchardNullifierDerivingKeyINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_nk( + _pointer, _uniffiStatus) + })) +} + +func (_self *OrchardFullViewingKey) Rivk() *OrchardCommitIvkRandomness { + _pointer := _self.ffiObject.incrementPointer("*OrchardFullViewingKey") + defer _self.ffiObject.decrementPointer() + return FfiConverterOrchardCommitIvkRandomnessINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_method_orchardfullviewingkey_rivk( + _pointer, _uniffiStatus) + })) +} + +func (object *OrchardFullViewingKey) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() +} + +type FfiConverterOrchardFullViewingKey struct{} + +var FfiConverterOrchardFullViewingKeyINSTANCE = FfiConverterOrchardFullViewingKey{} + +func (c FfiConverterOrchardFullViewingKey) Lift(pointer unsafe.Pointer) *OrchardFullViewingKey { + result := &OrchardFullViewingKey{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_frost_uniffi_sdk_fn_free_orchardfullviewingkey(pointer, status) + }), + } + runtime.SetFinalizer(result, (*OrchardFullViewingKey).Destroy) + return result +} + +func (c FfiConverterOrchardFullViewingKey) Read(reader io.Reader) *OrchardFullViewingKey { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterOrchardFullViewingKey) Lower(value *OrchardFullViewingKey) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*OrchardFullViewingKey") + defer value.ffiObject.decrementPointer() + return pointer +} + +func (c FfiConverterOrchardFullViewingKey) Write(writer io.Writer, value *OrchardFullViewingKey) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerOrchardFullViewingKey struct{} + +func (_ FfiDestroyerOrchardFullViewingKey) Destroy(value *OrchardFullViewingKey) { + value.Destroy() +} + +type OrchardKeyParts struct { + ffiObject FfiObject +} + +func OrchardKeyPartsRandom(network ZcashNetwork) (*OrchardKeyParts, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeOrchardKeyError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_constructor_orchardkeyparts_random(FfiConverterTypeZcashNetworkINSTANCE.Lower(network), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *OrchardKeyParts + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterOrchardKeyPartsINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func (object *OrchardKeyParts) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() +} + +type FfiConverterOrchardKeyParts struct{} + +var FfiConverterOrchardKeyPartsINSTANCE = FfiConverterOrchardKeyParts{} + +func (c FfiConverterOrchardKeyParts) Lift(pointer unsafe.Pointer) *OrchardKeyParts { + result := &OrchardKeyParts{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_frost_uniffi_sdk_fn_free_orchardkeyparts(pointer, status) + }), + } + runtime.SetFinalizer(result, (*OrchardKeyParts).Destroy) + return result +} + +func (c FfiConverterOrchardKeyParts) Read(reader io.Reader) *OrchardKeyParts { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterOrchardKeyParts) Lower(value *OrchardKeyParts) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*OrchardKeyParts") + defer value.ffiObject.decrementPointer() + return pointer +} + +func (c FfiConverterOrchardKeyParts) Write(writer io.Writer, value *OrchardKeyParts) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerOrchardKeyParts struct{} + +func (_ FfiDestroyerOrchardKeyParts) Destroy(value *OrchardKeyParts) { + value.Destroy() +} + +type OrchardNullifierDerivingKey struct { + ffiObject FfiObject +} + +func NewOrchardNullifierDerivingKey(bytes []byte) (*OrchardNullifierDerivingKey, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeOrchardKeyError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_constructor_orchardnullifierderivingkey_new(FfiConverterBytesINSTANCE.Lower(bytes), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *OrchardNullifierDerivingKey + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterOrchardNullifierDerivingKeyINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func (_self *OrchardNullifierDerivingKey) ToBytes() []byte { + _pointer := _self.ffiObject.incrementPointer("*OrchardNullifierDerivingKey") + defer _self.ffiObject.decrementPointer() + return FfiConverterBytesINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_method_orchardnullifierderivingkey_to_bytes( + _pointer, _uniffiStatus) + })) +} + +func (object *OrchardNullifierDerivingKey) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() +} + +type FfiConverterOrchardNullifierDerivingKey struct{} + +var FfiConverterOrchardNullifierDerivingKeyINSTANCE = FfiConverterOrchardNullifierDerivingKey{} + +func (c FfiConverterOrchardNullifierDerivingKey) Lift(pointer unsafe.Pointer) *OrchardNullifierDerivingKey { + result := &OrchardNullifierDerivingKey{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_frost_uniffi_sdk_fn_free_orchardnullifierderivingkey(pointer, status) + }), + } + runtime.SetFinalizer(result, (*OrchardNullifierDerivingKey).Destroy) + return result +} + +func (c FfiConverterOrchardNullifierDerivingKey) Read(reader io.Reader) *OrchardNullifierDerivingKey { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterOrchardNullifierDerivingKey) Lower(value *OrchardNullifierDerivingKey) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*OrchardNullifierDerivingKey") + defer value.ffiObject.decrementPointer() + return pointer +} + +func (c FfiConverterOrchardNullifierDerivingKey) Write(writer io.Writer, value *OrchardNullifierDerivingKey) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerOrchardNullifierDerivingKey struct{} + +func (_ FfiDestroyerOrchardNullifierDerivingKey) Destroy(value *OrchardNullifierDerivingKey) { + value.Destroy() +} + +type OrchardSpendValidatingKey struct { + ffiObject FfiObject +} + +func OrchardSpendValidatingKeyFromBytes(bytes []byte) (*OrchardSpendValidatingKey, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeOrchardKeyError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_constructor_orchardspendvalidatingkey_from_bytes(FfiConverterBytesINSTANCE.Lower(bytes), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *OrchardSpendValidatingKey + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterOrchardSpendValidatingKeyINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func (_self *OrchardSpendValidatingKey) ToBytes() []byte { + _pointer := _self.ffiObject.incrementPointer("*OrchardSpendValidatingKey") + defer _self.ffiObject.decrementPointer() + return FfiConverterBytesINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_method_orchardspendvalidatingkey_to_bytes( + _pointer, _uniffiStatus) + })) +} + +func (object *OrchardSpendValidatingKey) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() +} + +type FfiConverterOrchardSpendValidatingKey struct{} + +var FfiConverterOrchardSpendValidatingKeyINSTANCE = FfiConverterOrchardSpendValidatingKey{} + +func (c FfiConverterOrchardSpendValidatingKey) Lift(pointer unsafe.Pointer) *OrchardSpendValidatingKey { + result := &OrchardSpendValidatingKey{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_frost_uniffi_sdk_fn_free_orchardspendvalidatingkey(pointer, status) + }), + } + runtime.SetFinalizer(result, (*OrchardSpendValidatingKey).Destroy) + return result +} + +func (c FfiConverterOrchardSpendValidatingKey) Read(reader io.Reader) *OrchardSpendValidatingKey { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterOrchardSpendValidatingKey) Lower(value *OrchardSpendValidatingKey) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*OrchardSpendValidatingKey") + defer value.ffiObject.decrementPointer() + return pointer +} + +func (c FfiConverterOrchardSpendValidatingKey) Write(writer io.Writer, value *OrchardSpendValidatingKey) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerOrchardSpendValidatingKey struct{} + +func (_ FfiDestroyerOrchardSpendValidatingKey) Destroy(value *OrchardSpendValidatingKey) { + value.Destroy() +} + +type Configuration struct { + MinSigners uint16 + MaxSigners uint16 + Secret []byte +} + +func (r *Configuration) Destroy() { + FfiDestroyerUint16{}.Destroy(r.MinSigners) + FfiDestroyerUint16{}.Destroy(r.MaxSigners) + FfiDestroyerBytes{}.Destroy(r.Secret) +} + +type FfiConverterTypeConfiguration struct{} + +var FfiConverterTypeConfigurationINSTANCE = FfiConverterTypeConfiguration{} + +func (c FfiConverterTypeConfiguration) Lift(rb RustBufferI) Configuration { + return LiftFromRustBuffer[Configuration](c, rb) +} + +func (c FfiConverterTypeConfiguration) Read(reader io.Reader) Configuration { + return Configuration{ + FfiConverterUint16INSTANCE.Read(reader), + FfiConverterUint16INSTANCE.Read(reader), + FfiConverterBytesINSTANCE.Read(reader), + } +} + +func (c FfiConverterTypeConfiguration) Lower(value Configuration) RustBuffer { + return LowerIntoRustBuffer[Configuration](c, value) +} + +func (c FfiConverterTypeConfiguration) Write(writer io.Writer, value Configuration) { + FfiConverterUint16INSTANCE.Write(writer, value.MinSigners) + FfiConverterUint16INSTANCE.Write(writer, value.MaxSigners) + FfiConverterBytesINSTANCE.Write(writer, value.Secret) +} + +type FfiDestroyerTypeConfiguration struct{} + +func (_ FfiDestroyerTypeConfiguration) Destroy(value Configuration) { + value.Destroy() +} + +type DkgPart3Result struct { + PublicKeyPackage FrostPublicKeyPackage + KeyPackage FrostKeyPackage +} + +func (r *DkgPart3Result) Destroy() { + FfiDestroyerTypeFrostPublicKeyPackage{}.Destroy(r.PublicKeyPackage) + FfiDestroyerTypeFrostKeyPackage{}.Destroy(r.KeyPackage) +} + +type FfiConverterTypeDKGPart3Result struct{} + +var FfiConverterTypeDKGPart3ResultINSTANCE = FfiConverterTypeDKGPart3Result{} + +func (c FfiConverterTypeDKGPart3Result) Lift(rb RustBufferI) DkgPart3Result { + return LiftFromRustBuffer[DkgPart3Result](c, rb) +} + +func (c FfiConverterTypeDKGPart3Result) Read(reader io.Reader) DkgPart3Result { + return DkgPart3Result{ + FfiConverterTypeFrostPublicKeyPackageINSTANCE.Read(reader), + FfiConverterTypeFrostKeyPackageINSTANCE.Read(reader), + } +} + +func (c FfiConverterTypeDKGPart3Result) Lower(value DkgPart3Result) RustBuffer { + return LowerIntoRustBuffer[DkgPart3Result](c, value) } func (c FfiConverterTypeDKGPart3Result) Write(writer io.Writer, value DkgPart3Result) { @@ -1115,18 +1919,54 @@ func (c FfiConverterTypeFrostPublicKeyPackage) Read(reader io.Reader) FrostPubli } } -func (c FfiConverterTypeFrostPublicKeyPackage) Lower(value FrostPublicKeyPackage) RustBuffer { - return LowerIntoRustBuffer[FrostPublicKeyPackage](c, value) +func (c FfiConverterTypeFrostPublicKeyPackage) Lower(value FrostPublicKeyPackage) RustBuffer { + return LowerIntoRustBuffer[FrostPublicKeyPackage](c, value) +} + +func (c FfiConverterTypeFrostPublicKeyPackage) Write(writer io.Writer, value FrostPublicKeyPackage) { + FfiConverterMapTypeParticipantIdentifierStringINSTANCE.Write(writer, value.VerifyingShares) + FfiConverterStringINSTANCE.Write(writer, value.VerifyingKey) +} + +type FfiDestroyerTypeFrostPublicKeyPackage struct{} + +func (_ FfiDestroyerTypeFrostPublicKeyPackage) Destroy(value FrostPublicKeyPackage) { + value.Destroy() +} + +type FrostRandomizer struct { + Data []byte +} + +func (r *FrostRandomizer) Destroy() { + FfiDestroyerBytes{}.Destroy(r.Data) +} + +type FfiConverterTypeFrostRandomizer struct{} + +var FfiConverterTypeFrostRandomizerINSTANCE = FfiConverterTypeFrostRandomizer{} + +func (c FfiConverterTypeFrostRandomizer) Lift(rb RustBufferI) FrostRandomizer { + return LiftFromRustBuffer[FrostRandomizer](c, rb) +} + +func (c FfiConverterTypeFrostRandomizer) Read(reader io.Reader) FrostRandomizer { + return FrostRandomizer{ + FfiConverterBytesINSTANCE.Read(reader), + } +} + +func (c FfiConverterTypeFrostRandomizer) Lower(value FrostRandomizer) RustBuffer { + return LowerIntoRustBuffer[FrostRandomizer](c, value) } -func (c FfiConverterTypeFrostPublicKeyPackage) Write(writer io.Writer, value FrostPublicKeyPackage) { - FfiConverterMapTypeParticipantIdentifierStringINSTANCE.Write(writer, value.VerifyingShares) - FfiConverterStringINSTANCE.Write(writer, value.VerifyingKey) +func (c FfiConverterTypeFrostRandomizer) Write(writer io.Writer, value FrostRandomizer) { + FfiConverterBytesINSTANCE.Write(writer, value.Data) } -type FfiDestroyerTypeFrostPublicKeyPackage struct{} +type FfiDestroyerTypeFrostRandomizer struct{} -func (_ FfiDestroyerTypeFrostPublicKeyPackage) Destroy(value FrostPublicKeyPackage) { +func (_ FfiDestroyerTypeFrostRandomizer) Destroy(value FrostRandomizer) { value.Destroy() } @@ -1658,6 +2498,7 @@ var ErrCoordinationErrorSigningPackageSerializationError = fmt.Errorf("Coordinat var ErrCoordinationErrorSignatureShareDeserializationError = fmt.Errorf("CoordinationErrorSignatureShareDeserializationError") var ErrCoordinationErrorPublicKeyPackageDeserializationError = fmt.Errorf("CoordinationErrorPublicKeyPackageDeserializationError") var ErrCoordinationErrorSignatureShareAggregationFailed = fmt.Errorf("CoordinationErrorSignatureShareAggregationFailed") +var ErrCoordinationErrorInvalidRandomizer = fmt.Errorf("CoordinationErrorInvalidRandomizer") // Variant structs type CoordinationErrorFailedToCreateSigningPackage struct { @@ -1789,6 +2630,23 @@ func (self CoordinationErrorSignatureShareAggregationFailed) Is(target error) bo return target == ErrCoordinationErrorSignatureShareAggregationFailed } +type CoordinationErrorInvalidRandomizer struct { +} + +func NewCoordinationErrorInvalidRandomizer() *CoordinationError { + return &CoordinationError{ + err: &CoordinationErrorInvalidRandomizer{}, + } +} + +func (err CoordinationErrorInvalidRandomizer) Error() string { + return fmt.Sprint("InvalidRandomizer") +} + +func (self CoordinationErrorInvalidRandomizer) Is(target error) bool { + return target == ErrCoordinationErrorInvalidRandomizer +} + type FfiConverterTypeCoordinationError struct{} var FfiConverterTypeCoordinationErrorINSTANCE = FfiConverterTypeCoordinationError{} @@ -1821,6 +2679,8 @@ func (c FfiConverterTypeCoordinationError) Read(reader io.Reader) error { return &CoordinationError{&CoordinationErrorSignatureShareAggregationFailed{ Message: FfiConverterStringINSTANCE.Read(reader), }} + case 8: + return &CoordinationError{&CoordinationErrorInvalidRandomizer{}} default: panic(fmt.Sprintf("Unknown error code %d in FfiConverterTypeCoordinationError.Read()", errorID)) } @@ -1843,6 +2703,8 @@ func (c FfiConverterTypeCoordinationError) Write(writer io.Writer, value *Coordi case *CoordinationErrorSignatureShareAggregationFailed: writeInt32(writer, 7) FfiConverterStringINSTANCE.Write(writer, variantValue.Message) + case *CoordinationErrorInvalidRandomizer: + writeInt32(writer, 8) default: _ = variantValue panic(fmt.Sprintf("invalid error value `%v` in FfiConverterTypeCoordinationError.Write", value)) @@ -2904,6 +3766,164 @@ func (c FfiConverterTypeFrostSignatureVerificationError) Write(writer io.Writer, } } +type OrchardKeyError struct { + err error +} + +func (err OrchardKeyError) Error() string { + return fmt.Sprintf("OrchardKeyError: %s", err.err.Error()) +} + +func (err OrchardKeyError) Unwrap() error { + return err.err +} + +// Err* are used for checking error type with `errors.Is` +var ErrOrchardKeyErrorKeyDerivationError = fmt.Errorf("OrchardKeyErrorKeyDerivationError") +var ErrOrchardKeyErrorSerializationError = fmt.Errorf("OrchardKeyErrorSerializationError") +var ErrOrchardKeyErrorDeserializationError = fmt.Errorf("OrchardKeyErrorDeserializationError") +var ErrOrchardKeyErrorOtherError = fmt.Errorf("OrchardKeyErrorOtherError") + +// Variant structs +type OrchardKeyErrorKeyDerivationError struct { + Message string +} + +func NewOrchardKeyErrorKeyDerivationError( + message string, +) *OrchardKeyError { + return &OrchardKeyError{ + err: &OrchardKeyErrorKeyDerivationError{ + Message: message, + }, + } +} + +func (err OrchardKeyErrorKeyDerivationError) Error() string { + return fmt.Sprint("KeyDerivationError", + ": ", + + "Message=", + err.Message, + ) +} + +func (self OrchardKeyErrorKeyDerivationError) Is(target error) bool { + return target == ErrOrchardKeyErrorKeyDerivationError +} + +type OrchardKeyErrorSerializationError struct { +} + +func NewOrchardKeyErrorSerializationError() *OrchardKeyError { + return &OrchardKeyError{ + err: &OrchardKeyErrorSerializationError{}, + } +} + +func (err OrchardKeyErrorSerializationError) Error() string { + return fmt.Sprint("SerializationError") +} + +func (self OrchardKeyErrorSerializationError) Is(target error) bool { + return target == ErrOrchardKeyErrorSerializationError +} + +type OrchardKeyErrorDeserializationError struct { +} + +func NewOrchardKeyErrorDeserializationError() *OrchardKeyError { + return &OrchardKeyError{ + err: &OrchardKeyErrorDeserializationError{}, + } +} + +func (err OrchardKeyErrorDeserializationError) Error() string { + return fmt.Sprint("DeserializationError") +} + +func (self OrchardKeyErrorDeserializationError) Is(target error) bool { + return target == ErrOrchardKeyErrorDeserializationError +} + +type OrchardKeyErrorOtherError struct { + ErrorMessage string +} + +func NewOrchardKeyErrorOtherError( + errorMessage string, +) *OrchardKeyError { + return &OrchardKeyError{ + err: &OrchardKeyErrorOtherError{ + ErrorMessage: errorMessage, + }, + } +} + +func (err OrchardKeyErrorOtherError) Error() string { + return fmt.Sprint("OtherError", + ": ", + + "ErrorMessage=", + err.ErrorMessage, + ) +} + +func (self OrchardKeyErrorOtherError) Is(target error) bool { + return target == ErrOrchardKeyErrorOtherError +} + +type FfiConverterTypeOrchardKeyError struct{} + +var FfiConverterTypeOrchardKeyErrorINSTANCE = FfiConverterTypeOrchardKeyError{} + +func (c FfiConverterTypeOrchardKeyError) Lift(eb RustBufferI) error { + return LiftFromRustBuffer[error](c, eb) +} + +func (c FfiConverterTypeOrchardKeyError) Lower(value *OrchardKeyError) RustBuffer { + return LowerIntoRustBuffer[*OrchardKeyError](c, value) +} + +func (c FfiConverterTypeOrchardKeyError) Read(reader io.Reader) error { + errorID := readUint32(reader) + + switch errorID { + case 1: + return &OrchardKeyError{&OrchardKeyErrorKeyDerivationError{ + Message: FfiConverterStringINSTANCE.Read(reader), + }} + case 2: + return &OrchardKeyError{&OrchardKeyErrorSerializationError{}} + case 3: + return &OrchardKeyError{&OrchardKeyErrorDeserializationError{}} + case 4: + return &OrchardKeyError{&OrchardKeyErrorOtherError{ + ErrorMessage: FfiConverterStringINSTANCE.Read(reader), + }} + default: + panic(fmt.Sprintf("Unknown error code %d in FfiConverterTypeOrchardKeyError.Read()", errorID)) + } +} + +func (c FfiConverterTypeOrchardKeyError) Write(writer io.Writer, value *OrchardKeyError) { + switch variantValue := value.err.(type) { + case *OrchardKeyErrorKeyDerivationError: + writeInt32(writer, 1) + FfiConverterStringINSTANCE.Write(writer, variantValue.Message) + case *OrchardKeyErrorSerializationError: + writeInt32(writer, 2) + case *OrchardKeyErrorDeserializationError: + writeInt32(writer, 3) + case *OrchardKeyErrorOtherError: + writeInt32(writer, 4) + FfiConverterStringINSTANCE.Write(writer, variantValue.ErrorMessage) + default: + _ = variantValue + panic(fmt.Sprintf("invalid error value `%v` in FfiConverterTypeOrchardKeyError.Write", value)) + } +} + type Round1Error struct { err error } @@ -3032,6 +4052,7 @@ var ErrRound2ErrorNonceSerializationError = fmt.Errorf("Round2ErrorNonceSerializ var ErrRound2ErrorCommitmentSerializationError = fmt.Errorf("Round2ErrorCommitmentSerializationError") var ErrRound2ErrorSigningPackageDeserializationError = fmt.Errorf("Round2ErrorSigningPackageDeserializationError") var ErrRound2ErrorSigningFailed = fmt.Errorf("Round2ErrorSigningFailed") +var ErrRound2ErrorInvalidRandomizer = fmt.Errorf("Round2ErrorInvalidRandomizer") // Variant structs type Round2ErrorInvalidKeyPackage struct { @@ -3129,6 +4150,23 @@ func (self Round2ErrorSigningFailed) Is(target error) bool { return target == ErrRound2ErrorSigningFailed } +type Round2ErrorInvalidRandomizer struct { +} + +func NewRound2ErrorInvalidRandomizer() *Round2Error { + return &Round2Error{ + err: &Round2ErrorInvalidRandomizer{}, + } +} + +func (err Round2ErrorInvalidRandomizer) Error() string { + return fmt.Sprint("InvalidRandomizer") +} + +func (self Round2ErrorInvalidRandomizer) Is(target error) bool { + return target == ErrRound2ErrorInvalidRandomizer +} + type FfiConverterTypeRound2Error struct{} var FfiConverterTypeRound2ErrorINSTANCE = FfiConverterTypeRound2Error{} @@ -3157,6 +4195,8 @@ func (c FfiConverterTypeRound2Error) Read(reader io.Reader) error { return &Round2Error{&Round2ErrorSigningFailed{ Message: FfiConverterStringINSTANCE.Read(reader), }} + case 6: + return &Round2Error{&Round2ErrorInvalidRandomizer{}} default: panic(fmt.Sprintf("Unknown error code %d in FfiConverterTypeRound2Error.Read()", errorID)) } @@ -3175,12 +4215,46 @@ func (c FfiConverterTypeRound2Error) Write(writer io.Writer, value *Round2Error) case *Round2ErrorSigningFailed: writeInt32(writer, 5) FfiConverterStringINSTANCE.Write(writer, variantValue.Message) + case *Round2ErrorInvalidRandomizer: + writeInt32(writer, 6) default: _ = variantValue panic(fmt.Sprintf("invalid error value `%v` in FfiConverterTypeRound2Error.Write", value)) } } +type ZcashNetwork uint + +const ( + ZcashNetworkMainnet ZcashNetwork = 1 + ZcashNetworkTestnet ZcashNetwork = 2 +) + +type FfiConverterTypeZcashNetwork struct{} + +var FfiConverterTypeZcashNetworkINSTANCE = FfiConverterTypeZcashNetwork{} + +func (c FfiConverterTypeZcashNetwork) Lift(rb RustBufferI) ZcashNetwork { + return LiftFromRustBuffer[ZcashNetwork](c, rb) +} + +func (c FfiConverterTypeZcashNetwork) Lower(value ZcashNetwork) RustBuffer { + return LowerIntoRustBuffer[ZcashNetwork](c, value) +} +func (FfiConverterTypeZcashNetwork) Read(reader io.Reader) ZcashNetwork { + id := readInt32(reader) + return ZcashNetwork(id) +} + +func (FfiConverterTypeZcashNetwork) Write(writer io.Writer, value ZcashNetwork) { + writeInt32(writer, int32(value)) +} + +type FfiDestroyerTypeZcashNetwork struct{} + +func (_ FfiDestroyerTypeZcashNetwork) Destroy(value ZcashNetwork) { +} + type FfiConverterOptionalTypeParticipantIdentifier struct{} var FfiConverterOptionalTypeParticipantIdentifierINSTANCE = FfiConverterOptionalTypeParticipantIdentifier{} @@ -3523,9 +4597,9 @@ func (_ FfiDestroyerMapTypeParticipantIdentifierTypeFrostSecretKeyShare) Destroy } } -func Aggregate(signingPackage FrostSigningPackage, signatureShares []FrostSignatureShare, pubkeyPackage FrostPublicKeyPackage) (FrostSignature, error) { +func Aggregate(signingPackage FrostSigningPackage, signatureShares []FrostSignatureShare, pubkeyPackage FrostPublicKeyPackage, randomizer FrostRandomizer) (FrostSignature, error) { _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeCoordinationError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { - return C.uniffi_frost_uniffi_sdk_fn_func_aggregate(FfiConverterTypeFrostSigningPackageINSTANCE.Lower(signingPackage), FfiConverterSequenceTypeFrostSignatureShareINSTANCE.Lower(signatureShares), FfiConverterTypeFrostPublicKeyPackageINSTANCE.Lower(pubkeyPackage), _uniffiStatus) + return C.uniffi_frost_uniffi_sdk_fn_func_aggregate(FfiConverterTypeFrostSigningPackageINSTANCE.Lower(signingPackage), FfiConverterSequenceTypeFrostSignatureShareINSTANCE.Lower(signatureShares), FfiConverterTypeFrostPublicKeyPackageINSTANCE.Lower(pubkeyPackage), FfiConverterTypeFrostRandomizerINSTANCE.Lower(randomizer), _uniffiStatus) }) if _uniffiErr != nil { var _uniffiDefaultValue FrostSignature @@ -3535,6 +4609,30 @@ func Aggregate(signingPackage FrostSigningPackage, signatureShares []FrostSignat } } +func CommitmentToJson(commitment FrostSigningCommitments) (string, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_commitment_to_json(FfiConverterTypeFrostSigningCommitmentsINSTANCE.Lower(commitment), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue string + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterStringINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func FromHexString(hexString string) (FrostRandomizer, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_from_hex_string(FfiConverterStringINSTANCE.Lower(hexString), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue FrostRandomizer + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterTypeFrostRandomizerINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + func GenerateNoncesAndCommitments(keyPackage FrostKeyPackage) (FirstRoundCommitment, error) { _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeRound1Error{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { return C.uniffi_frost_uniffi_sdk_fn_func_generate_nonces_and_commitments(FfiConverterTypeFrostKeyPackageINSTANCE.Lower(keyPackage), _uniffiStatus) @@ -3577,6 +4675,78 @@ func IdentifierFromUint16(unsignedUint uint16) (ParticipantIdentifier, error) { } } +func JsonToCommitment(commitmentJson string, identifier ParticipantIdentifier) (FrostSigningCommitments, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_json_to_commitment(FfiConverterStringINSTANCE.Lower(commitmentJson), FfiConverterTypeParticipantIdentifierINSTANCE.Lower(identifier), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue FrostSigningCommitments + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterTypeFrostSigningCommitmentsINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func JsonToKeyPackage(keyPackageJson string) (FrostKeyPackage, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_json_to_key_package(FfiConverterStringINSTANCE.Lower(keyPackageJson), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue FrostKeyPackage + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterTypeFrostKeyPackageINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func JsonToPublicKeyPackage(publicKeyPackageJson string) (FrostPublicKeyPackage, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_json_to_public_key_package(FfiConverterStringINSTANCE.Lower(publicKeyPackageJson), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue FrostPublicKeyPackage + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterTypeFrostPublicKeyPackageINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func JsonToRandomizer(randomizerJson string) (FrostRandomizer, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_json_to_randomizer(FfiConverterStringINSTANCE.Lower(randomizerJson), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue FrostRandomizer + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterTypeFrostRandomizerINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func JsonToSignatureShare(signatureShareJson string, identifier ParticipantIdentifier) (FrostSignatureShare, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_json_to_signature_share(FfiConverterStringINSTANCE.Lower(signatureShareJson), FfiConverterTypeParticipantIdentifierINSTANCE.Lower(identifier), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue FrostSignatureShare + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterTypeFrostSignatureShareINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func KeyPackageToJson(keyPackage FrostKeyPackage) (string, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_key_package_to_json(FfiConverterTypeFrostKeyPackageINSTANCE.Lower(keyPackage), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue string + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterStringINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + func NewSigningPackage(message Message, commitments []FrostSigningCommitments) (FrostSigningPackage, error) { _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeCoordinationError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { return C.uniffi_frost_uniffi_sdk_fn_func_new_signing_package(FfiConverterTypeMessageINSTANCE.Lower(message), FfiConverterSequenceTypeFrostSigningCommitmentsINSTANCE.Lower(commitments), _uniffiStatus) @@ -3625,9 +4795,57 @@ func Part3(secretPackage *DkgRound2SecretPackage, round1Packages map[Participant } } -func Sign(signingPackage FrostSigningPackage, nonces FrostSigningNonces, keyPackage FrostKeyPackage) (FrostSignatureShare, error) { +func PublicKeyPackageToJson(publicKeyPackage FrostPublicKeyPackage) (string, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_public_key_package_to_json(FfiConverterTypeFrostPublicKeyPackageINSTANCE.Lower(publicKeyPackage), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue string + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterStringINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func RandomizedParamsFromPublicKeyAndSigningPackage(publicKey FrostPublicKeyPackage, signingPackage FrostSigningPackage) (*FrostRandomizedParams, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_frost_uniffi_sdk_fn_func_randomized_params_from_public_key_and_signing_package(FfiConverterTypeFrostPublicKeyPackageINSTANCE.Lower(publicKey), FfiConverterTypeFrostSigningPackageINSTANCE.Lower(signingPackage), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *FrostRandomizedParams + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterFrostRandomizedParamsINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func RandomizerFromParams(randomizedParams *FrostRandomizedParams) (FrostRandomizer, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_randomizer_from_params(FfiConverterFrostRandomizedParamsINSTANCE.Lower(randomizedParams), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue FrostRandomizer + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterTypeFrostRandomizerINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func RandomizerToJson(randomizer FrostRandomizer) (string, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_randomizer_to_json(FfiConverterTypeFrostRandomizerINSTANCE.Lower(randomizer), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue string + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterStringINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func Sign(signingPackage FrostSigningPackage, nonces FrostSigningNonces, keyPackage FrostKeyPackage, randomizer FrostRandomizer) (FrostSignatureShare, error) { _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeRound2Error{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { - return C.uniffi_frost_uniffi_sdk_fn_func_sign(FfiConverterTypeFrostSigningPackageINSTANCE.Lower(signingPackage), FfiConverterTypeFrostSigningNoncesINSTANCE.Lower(nonces), FfiConverterTypeFrostKeyPackageINSTANCE.Lower(keyPackage), _uniffiStatus) + return C.uniffi_frost_uniffi_sdk_fn_func_sign(FfiConverterTypeFrostSigningPackageINSTANCE.Lower(signingPackage), FfiConverterTypeFrostSigningNoncesINSTANCE.Lower(nonces), FfiConverterTypeFrostKeyPackageINSTANCE.Lower(keyPackage), FfiConverterTypeFrostRandomizerINSTANCE.Lower(randomizer), _uniffiStatus) }) if _uniffiErr != nil { var _uniffiDefaultValue FrostSignatureShare @@ -3637,6 +4855,18 @@ func Sign(signingPackage FrostSigningPackage, nonces FrostSigningNonces, keyPack } } +func SignatureSharePackageToJson(signatureShare FrostSignatureShare) (string, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_frost_uniffi_sdk_fn_func_signature_share_package_to_json(FfiConverterTypeFrostSignatureShareINSTANCE.Lower(signatureShare), _uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue string + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterStringINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + func TrustedDealerKeygenFrom(configuration Configuration) (TrustedKeyGeneration, error) { _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeFrostError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { return C.uniffi_frost_uniffi_sdk_fn_func_trusted_dealer_keygen_from(FfiConverterTypeConfigurationINSTANCE.Lower(configuration), _uniffiStatus) @@ -3681,6 +4911,14 @@ func VerifyAndGetKeyPackageFrom(secretShare FrostSecretKeyShare) (FrostKeyPackag } } +func VerifyRandomizedSignature(randomizer FrostRandomizer, message Message, signature FrostSignature, pubkey FrostPublicKeyPackage) error { + _, _uniffiErr := rustCallWithError(FfiConverterTypeFrostSignatureVerificationError{}, func(_uniffiStatus *C.RustCallStatus) bool { + C.uniffi_frost_uniffi_sdk_fn_func_verify_randomized_signature(FfiConverterTypeFrostRandomizerINSTANCE.Lower(randomizer), FfiConverterTypeMessageINSTANCE.Lower(message), FfiConverterTypeFrostSignatureINSTANCE.Lower(signature), FfiConverterTypeFrostPublicKeyPackageINSTANCE.Lower(pubkey), _uniffiStatus) + return false + }) + return _uniffiErr +} + func VerifySignature(message Message, signature FrostSignature, pubkey FrostPublicKeyPackage) error { _, _uniffiErr := rustCallWithError(FfiConverterTypeFrostSignatureVerificationError{}, func(_uniffiStatus *C.RustCallStatus) bool { C.uniffi_frost_uniffi_sdk_fn_func_verify_signature(FfiConverterTypeMessageINSTANCE.Lower(message), FfiConverterTypeFrostSignatureINSTANCE.Lower(signature), FfiConverterTypeFrostPublicKeyPackageINSTANCE.Lower(pubkey), _uniffiStatus)