Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 30 additions & 117 deletions packages/wasm-mps/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,20 +253,15 @@ mod mps {
/// Process round 1 of DSG protocol.
/// round1_messages: Public messages from other parties.
/// state: Private state result from round 0.
pub fn dsg_round1_process(
round1_messages: &[Vec<u8>; 2],
state: &[u8],
) -> Result<MsgState, MpsError> {
pub fn dsg_round1_process(round1_message: &[u8], state: &[u8]) -> Result<MsgState, MpsError> {
// Parse state
let state: DsgStateR1 =
bincode::deserialize(state).map_err(|_| MpsError::DeserializationError)?;

// Parse messages
let i0_msg1: SignMsg1 = bincode::deserialize(round1_messages[0].as_slice())
.map_err(|_| MpsError::DeserializationError)?;
let i1_msg1: SignMsg1 = bincode::deserialize(round1_messages[1].as_slice())
.map_err(|_| MpsError::DeserializationError)?;
let msgs = vec![i0_msg1, i1_msg1, state.msg];
let i0_msg1: SignMsg1 =
bincode::deserialize(round1_message).map_err(|_| MpsError::DeserializationError)?;
let msgs = vec![i0_msg1, state.msg];

// Process all round1 messages together
let (p2, msg2) = state
Expand All @@ -289,20 +284,15 @@ mod mps {
/// Process round 2 of DSG protocol.
/// round2_messages: Public messages from other parties.
/// state: Private state result from round 1.
pub fn dsg_round2_process(
round2_messages: &[Vec<u8>; 2],
state: &[u8],
) -> Result<MsgState, MpsError> {
pub fn dsg_round2_process(round2_message: &[u8], state: &[u8]) -> Result<MsgState, MpsError> {
// Parse state
let state: DsgStateR2 =
bincode::deserialize(state).map_err(|_| MpsError::DeserializationError)?;

// Parse messages
let i0_msg2: SignMsg2<EdwardsPoint> = bincode::deserialize(round2_messages[0].as_slice())
.map_err(|_| MpsError::DeserializationError)?;
let i1_msg2: SignMsg2<EdwardsPoint> = bincode::deserialize(round2_messages[1].as_slice())
.map_err(|_| MpsError::DeserializationError)?;
let msgs = vec![i0_msg2, i1_msg2, state.msg];
let i0_msg2: SignMsg2<EdwardsPoint> =
bincode::deserialize(round2_message).map_err(|_| MpsError::DeserializationError)?;
let msgs = vec![i0_msg2, state.msg];

// Process all round2 messages together
let party = state
Expand All @@ -328,20 +318,15 @@ mod mps {
/// Process round 3 of DSG protocol.
/// round3_messages: Public messages from other parties.
/// state: Private state result from round 2.
pub fn dsg_round3_process(
round3_messages: &[Vec<u8>; 2],
state: &[u8],
) -> Result<Vec<u8>, MpsError> {
pub fn dsg_round3_process(round3_message: &[u8], state: &[u8]) -> Result<Vec<u8>, MpsError> {
// Parse state
let state: DsgStateR3 =
bincode::deserialize(state).map_err(|_| MpsError::DeserializationError)?;

// Parse messages
let i0_msg3: SignMsg3<EdwardsPoint> = bincode::deserialize(round3_messages[0].as_slice())
.map_err(|_| MpsError::DeserializationError)?;
let i1_msg3: SignMsg3<EdwardsPoint> = bincode::deserialize(round3_messages[1].as_slice())
.map_err(|_| MpsError::DeserializationError)?;
let msgs = vec![i0_msg3, i1_msg3, state.msg];
let i0_msg3: SignMsg3<EdwardsPoint> =
bincode::deserialize(round3_message).map_err(|_| MpsError::DeserializationError)?;
let msgs = vec![i0_msg3, state.msg];

// Process all round2 messages together
let (signature, _) = state
Expand Down Expand Up @@ -512,11 +497,6 @@ mod tests {
dkg_p0_1.state.as_slice(),
)
.unwrap();
let dkg_p1_share = mps::dkg_round2_process(
&[dkg_p0_1.msg.clone(), dkg_p2_1.msg.clone()],
dkg_p1_1.state.as_slice(),
)
.unwrap();
let dkg_p2_share = mps::dkg_round2_process(
&[dkg_p0_1.msg.clone(), dkg_p1_1.msg.clone()],
dkg_p2_1.state.as_slice(),
Expand All @@ -529,70 +509,31 @@ mod tests {
// Process DSG round 0
let dsg_p0_0 =
mps::dsg_round0_process(dkg_p0_share.share.as_slice(), "m".to_string(), msg).unwrap();
let dsg_p1_0 =
mps::dsg_round0_process(dkg_p1_share.share.as_slice(), "m".to_string(), msg).unwrap();
let dsg_p2_0 =
mps::dsg_round0_process(dkg_p2_share.share.as_slice(), "m".to_string(), msg).unwrap();

// Process DSG round 1
let dsg_p0_1 = mps::dsg_round1_process(
&[dsg_p1_0.msg.clone(), dsg_p2_0.msg.clone()],
dsg_p0_0.state.as_slice(),
)
.unwrap();
let dsg_p1_1 = mps::dsg_round1_process(
&[dsg_p0_0.msg.clone(), dsg_p2_0.msg.clone()],
dsg_p1_0.state.as_slice(),
)
.unwrap();
let dsg_p2_1 = mps::dsg_round1_process(
&[dsg_p0_0.msg.clone(), dsg_p1_0.msg.clone()],
dsg_p2_0.state.as_slice(),
)
.unwrap();
let dsg_p0_1 =
mps::dsg_round1_process(dsg_p2_0.msg.as_slice(), dsg_p0_0.state.as_slice()).unwrap();
let dsg_p2_1 =
mps::dsg_round1_process(dsg_p0_0.msg.as_slice(), dsg_p2_0.state.as_slice()).unwrap();

// Process DSG round 2
let dsg_p0_2 = mps::dsg_round2_process(
&[dsg_p1_1.msg.clone(), dsg_p2_1.msg.clone()],
dsg_p0_1.state.as_slice(),
)
.unwrap();
let dsg_p1_2 = mps::dsg_round2_process(
&[dsg_p0_1.msg.clone(), dsg_p2_1.msg.clone()],
dsg_p1_1.state.as_slice(),
)
.unwrap();
let dsg_p2_2 = mps::dsg_round2_process(
&[dsg_p0_1.msg.clone(), dsg_p1_1.msg.clone()],
dsg_p2_1.state.as_slice(),
)
.unwrap();
let dsg_p0_2 =
mps::dsg_round2_process(dsg_p2_1.msg.as_slice(), dsg_p0_1.state.as_slice()).unwrap();
let dsg_p2_2 =
mps::dsg_round2_process(dsg_p0_1.msg.as_slice(), dsg_p2_1.state.as_slice()).unwrap();

// Process DSG round 3
let dsg_p0_sig = mps::dsg_round3_process(
&[dsg_p1_2.msg.clone(), dsg_p2_2.msg.clone()],
dsg_p0_2.state.as_slice(),
)
.unwrap();
let dsg_p1_sig = mps::dsg_round3_process(
&[dsg_p0_2.msg.clone(), dsg_p2_2.msg.clone()],
dsg_p1_2.state.as_slice(),
)
.unwrap();
let dsg_p2_sig = mps::dsg_round3_process(
&[dsg_p0_2.msg.clone(), dsg_p1_2.msg.clone()],
dsg_p2_2.state.as_slice(),
)
.unwrap();
let dsg_p0_sig =
mps::dsg_round3_process(dsg_p2_2.msg.as_slice(), dsg_p0_2.state.as_slice()).unwrap();
let dsg_p2_sig =
mps::dsg_round3_process(dsg_p0_2.msg.as_slice(), dsg_p2_2.state.as_slice()).unwrap();

assert_eq!(
dsg_p2_sig, dsg_p0_sig,
"Party 0 signature differs from party 2 signature"
);
assert_eq!(
dsg_p2_sig, dsg_p1_sig,
"Party 1 signature differs from party 2 signature"
);

// Verify signature
VerifyingKey::from_bytes(&dkg_p0_share.pk)
Expand All @@ -602,13 +543,6 @@ mod tests {
&Signature::from_bytes(dsg_p0_sig.as_slice().try_into().unwrap()),
)
.unwrap();
VerifyingKey::from_bytes(&dkg_p1_share.pk)
.unwrap()
.verify(
msg,
&Signature::from_bytes(dsg_p1_sig.as_slice().try_into().unwrap()),
)
.unwrap();
VerifyingKey::from_bytes(&dkg_p2_share.pk)
.unwrap()
.verify(
Expand Down Expand Up @@ -760,15 +694,8 @@ pub fn dsg_round0_process(
}

#[wasm_bindgen]
pub fn dsg_round1_process(round1_messages: Array, state: &[u8]) -> Result<MsgState, String> {
let result = mps::dsg_round1_process(
&[
js_sys::Uint8Array::from(round1_messages.get(0)).to_vec(),
js_sys::Uint8Array::from(round1_messages.get(1)).to_vec(),
],
state,
)
.map_err(|e| e.to_string())?;
pub fn dsg_round1_process(round1_message: &[u8], state: &[u8]) -> Result<MsgState, String> {
let result = mps::dsg_round1_process(round1_message, state).map_err(|e| e.to_string())?;

Ok(MsgState {
msg: result.msg,
Expand All @@ -777,15 +704,8 @@ pub fn dsg_round1_process(round1_messages: Array, state: &[u8]) -> Result<MsgSta
}

#[wasm_bindgen]
pub fn dsg_round2_process(round2_messages: Array, state: &[u8]) -> Result<MsgState, String> {
let result = mps::dsg_round2_process(
&[
js_sys::Uint8Array::from(round2_messages.get(0)).to_vec(),
js_sys::Uint8Array::from(round2_messages.get(1)).to_vec(),
],
state,
)
.map_err(|e| e.to_string())?;
pub fn dsg_round2_process(round2_message: &[u8], state: &[u8]) -> Result<MsgState, String> {
let result = mps::dsg_round2_process(round2_message, state).map_err(|e| e.to_string())?;

Ok(MsgState {
msg: result.msg,
Expand All @@ -794,15 +714,8 @@ pub fn dsg_round2_process(round2_messages: Array, state: &[u8]) -> Result<MsgSta
}

#[wasm_bindgen]
pub fn dsg_round3_process(round2_messages: Array, state: &[u8]) -> Result<Vec<u8>, String> {
let result = mps::dsg_round3_process(
&[
js_sys::Uint8Array::from(round2_messages.get(0)).to_vec(),
js_sys::Uint8Array::from(round2_messages.get(1)).to_vec(),
],
state,
)
.map_err(|e| e.to_string())?;
pub fn dsg_round3_process(round2_message: &[u8], state: &[u8]) -> Result<Vec<u8>, String> {
let result = mps::dsg_round3_process(round2_message, state).map_err(|e| e.to_string())?;

Ok(result.to_vec())
}
45 changes: 15 additions & 30 deletions packages/wasm-mps/test/mps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ describe("mps", function () {
});

describe("dsg", function () {
const otherIndex = [1, 0];
let shares: Array<mps.Share>;

before("performs dkg", function () {
Expand Down Expand Up @@ -223,67 +224,51 @@ describe("mps", function () {
);

it("performs round 0", function () {
for (let i = 0; i < 3; i++) {
for (const i of [0, 2]) {
mps.dsg_round0_process(shares[i].share, "m", message);
}
});

let results1: Array<mps.MsgState>;

before("performs round 0", function () {
results1 = [0, 1, 2].map((i) => mps.dsg_round0_process(shares[i].share, "m", message));
results1 = [0, 2].map((i) => mps.dsg_round0_process(shares[i].share, "m", message));
});

it("performs round 1", function () {
for (let i = 0; i < 3; i++) {
mps.dsg_round1_process(
otherIndices[i].map((i) => results1[i].msg),
results1[i].state,
);
for (let i = 0; i < 2; i++) {
mps.dsg_round1_process(results1[otherIndex[i]].msg, results1[i].state);
}
});

let results2: Array<mps.MsgState>;

before("performs round 1", function () {
results2 = [0, 1, 2].map((i) =>
mps.dsg_round1_process(
otherIndices[i].map((i) => results1[i].msg),
results1[i].state,
),
results2 = [0, 1].map((i) =>
mps.dsg_round1_process(results1[otherIndex[i]].msg, results1[i].state),
);
});

it("performs round 2", function () {
for (let i = 0; i < 3; i++) {
mps.dsg_round2_process(
otherIndices[i].map((i) => results2[i].msg),
results2[i].state,
);
for (let i = 0; i < 2; i++) {
mps.dsg_round2_process(results2[otherIndex[i]].msg, results2[i].state);
}
});

let results3: Array<mps.MsgState>;

before("performs round 2", function () {
results3 = [0, 1, 2].map((i) =>
mps.dsg_round2_process(
otherIndices[i].map((i) => results2[i].msg),
results2[i].state,
),
results3 = [0, 1].map((i) =>
mps.dsg_round2_process(results2[otherIndex[i]].msg, results2[i].state),
);
});

it("performs round 3", function () {
const signatures = [0, 1, 2].map((i) =>
mps.dsg_round3_process(
otherIndices[i].map((i) => results3[i].msg),
results3[i].state,
),
const signatures = [0, 1].map((i) =>
mps.dsg_round3_process(results3[otherIndex[i]].msg, results3[i].state),
);
for (let i = 0; i < 3; i++) {
assert(sodium.crypto_sign_verify_detached(signatures[i], message, shares[i].pk));
}
assert(sodium.crypto_sign_verify_detached(signatures[0], message, shares[0].pk));
assert(sodium.crypto_sign_verify_detached(signatures[1], message, shares[2].pk));
});
});
});
Loading