Skip to content

Commit

Permalink
feat(ironfish): Update multisig store to use identity as a key (#4800)
Browse files Browse the repository at this point in the history
* WIP

* Fix import

* Create signing commitment

* Fix lint

* Undo jest

* Fix test
  • Loading branch information
rohanjadvani authored Mar 4, 2024
1 parent 38a30d3 commit 7421b42
Show file tree
Hide file tree
Showing 34 changed files with 554 additions and 167 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions ironfish-rust-nodejs/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
/* auto-generated by NAPI-RS */

export const IDENTITY_LEN: number
export function createSigningCommitment(identity: string, keyPackage: string, transactionHash: Buffer, signers: Array<string>): string
export function createSignatureShare(identity: string, keyPackage: string, signingPackage: string): string
export const SECRET_LEN: number
export function createSigningCommitment(secret: string, keyPackage: string, transactionHash: Buffer, signers: Array<string>): string
export function createSignatureShare(secret: string, keyPackage: string, signingPackage: string): string
export function generateAndSplitKey(minSigners: number, identities: Array<string>): TrustedDealerKeyPackages
export interface ParticipantKeyPackage {
identity: string
Expand Down Expand Up @@ -113,6 +114,11 @@ export class PublicKeyPackage {
constructor(value: string)
identities(): Array<Buffer>
}
export type NativeSigningCommitment = SigningCommitment
export class SigningCommitment {
constructor(jsBytes: Buffer)
identity(): Buffer
}
export class BoxKeyPair {
constructor()
static fromHex(secretHex: string): BoxKeyPair
Expand Down
4 changes: 3 additions & 1 deletion ironfish-rust-nodejs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,16 +252,18 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}

const { FishHashContext, IDENTITY_LEN, createSigningCommitment, createSignatureShare, ParticipantSecret, ParticipantIdentity, generateAndSplitKey, PublicKeyPackage, contribute, verifyTransform, KEY_LENGTH, NONCE_LENGTH, BoxKeyPair, randomBytes, boxMessage, unboxMessage, RollingFilter, initSignalHandler, triggerSegfault, ASSET_ID_LENGTH, ASSET_METADATA_LENGTH, ASSET_NAME_LENGTH, ASSET_LENGTH, Asset, NOTE_ENCRYPTION_KEY_LENGTH, MAC_LENGTH, ENCRYPTED_NOTE_PLAINTEXT_LENGTH, ENCRYPTED_NOTE_LENGTH, NoteEncrypted, PUBLIC_ADDRESS_LENGTH, RANDOMNESS_LENGTH, MEMO_LENGTH, AMOUNT_VALUE_LENGTH, DECRYPTED_NOTE_LENGTH, Note, PROOF_LENGTH, TRANSACTION_SIGNATURE_LENGTH, TRANSACTION_PUBLIC_KEY_RANDOMNESS_LENGTH, TRANSACTION_EXPIRATION_LENGTH, TRANSACTION_FEE_LENGTH, LATEST_TRANSACTION_VERSION, TransactionPosted, Transaction, verifyTransactions, UnsignedTransaction, aggregateSignatureShares, LanguageCode, generateKey, spendingKeyToWords, wordsToSpendingKey, generateKeyFromPrivateKey, initializeSapling, FoundBlockResult, ThreadPoolHandler, isValidPublicAddress } = nativeBinding
const { FishHashContext, IDENTITY_LEN, SECRET_LEN, createSigningCommitment, createSignatureShare, ParticipantSecret, ParticipantIdentity, generateAndSplitKey, PublicKeyPackage, SigningCommitment, contribute, verifyTransform, KEY_LENGTH, NONCE_LENGTH, BoxKeyPair, randomBytes, boxMessage, unboxMessage, RollingFilter, initSignalHandler, triggerSegfault, ASSET_ID_LENGTH, ASSET_METADATA_LENGTH, ASSET_NAME_LENGTH, ASSET_LENGTH, Asset, NOTE_ENCRYPTION_KEY_LENGTH, MAC_LENGTH, ENCRYPTED_NOTE_PLAINTEXT_LENGTH, ENCRYPTED_NOTE_LENGTH, NoteEncrypted, PUBLIC_ADDRESS_LENGTH, RANDOMNESS_LENGTH, MEMO_LENGTH, AMOUNT_VALUE_LENGTH, DECRYPTED_NOTE_LENGTH, Note, PROOF_LENGTH, TRANSACTION_SIGNATURE_LENGTH, TRANSACTION_PUBLIC_KEY_RANDOMNESS_LENGTH, TRANSACTION_EXPIRATION_LENGTH, TRANSACTION_FEE_LENGTH, LATEST_TRANSACTION_VERSION, TransactionPosted, Transaction, verifyTransactions, UnsignedTransaction, aggregateSignatureShares, LanguageCode, generateKey, spendingKeyToWords, wordsToSpendingKey, generateKeyFromPrivateKey, initializeSapling, FoundBlockResult, ThreadPoolHandler, isValidPublicAddress } = nativeBinding

module.exports.FishHashContext = FishHashContext
module.exports.IDENTITY_LEN = IDENTITY_LEN
module.exports.SECRET_LEN = SECRET_LEN
module.exports.createSigningCommitment = createSigningCommitment
module.exports.createSignatureShare = createSignatureShare
module.exports.ParticipantSecret = ParticipantSecret
module.exports.ParticipantIdentity = ParticipantIdentity
module.exports.generateAndSplitKey = generateAndSplitKey
module.exports.PublicKeyPackage = PublicKeyPackage
module.exports.SigningCommitment = SigningCommitment
module.exports.contribute = contribute
module.exports.verifyTransform = verifyTransform
module.exports.KEY_LENGTH = KEY_LENGTH
Expand Down
40 changes: 31 additions & 9 deletions ironfish-rust-nodejs/src/frost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ use std::ops::Deref;
#[napi]
pub const IDENTITY_LEN: u32 = ironfish::frost_utils::IDENTITY_LEN as u32;

#[napi]
pub const SECRET_LEN: u32 = ironfish_frost::participant::SECRET_LEN as u32;

fn try_deserialize_identities<I, S>(signers: I) -> Result<Vec<Identity>>
where
I: IntoIterator<Item = S>,
Expand All @@ -43,13 +46,12 @@ where

#[napi]
pub fn create_signing_commitment(
identity: String,
secret: String,
key_package: String,
transaction_hash: JsBuffer,
signers: Vec<String>,
) -> Result<String> {
let identity =
Identity::deserialize_from(&hex_to_vec_bytes(&identity).map_err(to_napi_err)?[..])?;
let secret = Secret::deserialize_from(&hex_to_vec_bytes(&secret).map_err(to_napi_err)?[..])?;
let key_package =
KeyPackage::deserialize(&hex_to_vec_bytes(&key_package).map_err(to_napi_err)?)
.map_err(to_napi_err)?;
Expand All @@ -61,7 +63,7 @@ pub fn create_signing_commitment(
let commitments = SigningCommitments::from(&nonces);

let signing_commitment =
SigningCommitment::from_frost(identity, *commitments.hiding(), *commitments.binding());
SigningCommitment::from_frost(secret, *commitments.hiding(), *commitments.binding());

let bytes = signing_commitment.serialize()?;

Expand All @@ -70,13 +72,12 @@ pub fn create_signing_commitment(

#[napi]
pub fn create_signature_share(
identity: String,
secret: String,
key_package: String,
signing_package: String,
) -> Result<String> {
let identity =
Identity::deserialize_from(&hex_to_vec_bytes(&identity).map_err(to_napi_err)?[..])
.map_err(to_napi_err)?;
let secret = Secret::deserialize_from(&hex_to_vec_bytes(&secret).map_err(to_napi_err)?[..])?;
let identity = secret.to_identity();
let key_package =
KeyPackage::deserialize(&hex_to_vec_bytes(&key_package).map_err(to_napi_err)?[..])
.map_err(to_napi_err)?;
Expand Down Expand Up @@ -113,7 +114,7 @@ pub fn create_signature_share(
.map_err(to_napi_err)?;

let signature_share = SignatureShare::from_frost(signature_share, identity);
let bytes = signature_share.serialize()?;
let bytes = signature_share.serialize();

Ok(bytes_to_hex(&bytes[..]))
}
Expand Down Expand Up @@ -275,3 +276,24 @@ impl NativePublicKeyPackage {
.collect()
}
}

#[napi(js_name = "SigningCommitment")]
pub struct NativeSigningCommitment {
signing_commitment: SigningCommitment,
}

#[napi]
impl NativeSigningCommitment {
#[napi(constructor)]
pub fn new(js_bytes: JsBuffer) -> Result<NativeSigningCommitment> {
let bytes = js_bytes.into_value()?;
SigningCommitment::deserialize_from(bytes.as_ref())
.map(|signing_commitment| NativeSigningCommitment { signing_commitment })
.map_err(to_napi_err)
}

#[napi]
pub fn identity(&self) -> Buffer {
Buffer::from(self.signing_commitment.identity().serialize().as_slice())
}
}
Loading

0 comments on commit 7421b42

Please sign in to comment.