From 7413250a63ef568369c01776b1433e9d1f061596 Mon Sep 17 00:00:00 2001 From: Hugh Cunningham <57735705+hughy@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:54:22 -0700 Subject: [PATCH] defines from_frost factory method on NativePublicKeyPackage (#5381) allows us to construct a PublicKeyPackage from the raw parts: the frost public key package, the list of signer identities, and the minimum number of signers following the round3_min changes to ironfish-frost the Ledger app will produce a raw frost public key package at the end of DKG round3, so we will need to construct the ironfish-frost PublicKeyPackage from its parts --- ironfish-rust-nodejs/index.d.ts | 3 +++ ironfish-rust-nodejs/src/multisig.rs | 38 +++++++++++++++++++++++++++- ironfish/src/multisig.test.slow.ts | 18 +++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/ironfish-rust-nodejs/index.d.ts b/ironfish-rust-nodejs/index.d.ts index 4e4a05af4e..eb4ed16352 100644 --- a/ironfish-rust-nodejs/index.d.ts +++ b/ironfish-rust-nodejs/index.d.ts @@ -354,7 +354,10 @@ export namespace multisig { export type NativePublicKeyPackage = PublicKeyPackage export class PublicKeyPackage { constructor(value: string) + static fromFrost(frostPublicKeyPackage: Buffer, identities: Array, minSigners: number): NativePublicKeyPackage + serialize(): Buffer identities(): Array + frostPublicKeyPackage(): Buffer minSigners(): number } export type NativeSigningCommitment = SigningCommitment diff --git a/ironfish-rust-nodejs/src/multisig.rs b/ironfish-rust-nodejs/src/multisig.rs index bb5f4b2a3d..dde0171e5f 100644 --- a/ironfish-rust-nodejs/src/multisig.rs +++ b/ironfish-rust-nodejs/src/multisig.rs @@ -5,7 +5,10 @@ use crate::{structs::NativeUnsignedTransaction, to_napi_err}; use ironfish::{ frost::{ - frost::{round1::SigningCommitments, round2::SignatureShare as FrostSignatureShare}, + frost::{ + keys::PublicKeyPackage as FrostPublicKeyPackage, round1::SigningCommitments, + round2::SignatureShare as FrostSignatureShare, + }, keys::KeyPackage, round2, Randomizer, }, @@ -351,6 +354,28 @@ impl NativePublicKeyPackage { Ok(NativePublicKeyPackage { public_key_package }) } + #[napi(factory)] + pub fn from_frost( + frost_public_key_package: JsBuffer, + identities: Vec, + min_signers: u16, + ) -> Result { + let frost_public_key_package = + FrostPublicKeyPackage::deserialize(frost_public_key_package.into_value()?.as_ref()) + .map_err(to_napi_err)?; + let identities = try_deserialize_identities(identities)?; + + let public_key_package = + PublicKeyPackage::from_frost(frost_public_key_package, identities, min_signers); + + Ok(NativePublicKeyPackage { public_key_package }) + } + + #[napi] + pub fn serialize(&self) -> Buffer { + Buffer::from(self.public_key_package.serialize()) + } + #[napi] pub fn identities(&self) -> Vec { self.public_key_package @@ -360,6 +385,17 @@ impl NativePublicKeyPackage { .collect() } + #[napi] + pub fn frost_public_key_package(&self) -> Result { + Ok(Buffer::from( + self.public_key_package + .frost_public_key_package() + .serialize() + .map_err(to_napi_err)? + .as_slice(), + )) + } + #[napi] pub fn min_signers(&self) -> u16 { self.public_key_package.min_signers() diff --git a/ironfish/src/multisig.test.slow.ts b/ironfish/src/multisig.test.slow.ts index a6a3e01955..f07eaa92c6 100644 --- a/ironfish/src/multisig.test.slow.ts +++ b/ironfish/src/multisig.test.slow.ts @@ -54,6 +54,24 @@ describe('multisig', () => { const publicAddress = round3Packages[0].publicAddress + // Ensure that we can construct PublicKeyPackage from the raw frost public + // key package + for (const round3Package of round3Packages) { + const deserializedPublicKeyPackage = new multisig.PublicKeyPackage( + round3Package.publicKeyPackage, + ) + + const publicKeyPackage = multisig.PublicKeyPackage.fromFrost( + deserializedPublicKeyPackage.frostPublicKeyPackage(), + deserializedPublicKeyPackage.identities().map((i) => i.toString('hex')), + deserializedPublicKeyPackage.minSigners(), + ) + + expect(publicKeyPackage.serialize().toString('hex')).toEqual( + round3Package.publicKeyPackage, + ) + } + const raw = new RawTransaction(TransactionVersion.V1) const inNote = new NativeNote(