Skip to content

Commit

Permalink
from array to struct fields
Browse files Browse the repository at this point in the history
  • Loading branch information
max-zengo committed May 26, 2024
1 parent a547905 commit 9f93c6a
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 70 deletions.
7 changes: 3 additions & 4 deletions examples/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,12 @@ fn launch_party(
let (private_nonces, public_nonces) = keypair.generate_partial_nonces(Some(MESSAGE));

// Send your public nonces to the counterparty.
sender.send(public_nonces.serialize()).unwrap();
sender.send(public_nonces.serialize().to_vec()).unwrap();
// Receive the counterparty's nonces.

let other_party_nonces = PublicPartialNonces::deserialize(
receiver
.recv_array::<64>()
.map_err(|_| "Public nonces are 64 bytes")?.to_vec()
.recv_array()
.map_err(|_| "Public nonces are 64 bytes")?,
)
.ok_or("Received invalid public nonces")?;

Expand Down
17 changes: 13 additions & 4 deletions src/keypair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ impl KeyPair {
// is the sum of partial_nonces[i] from both parties
// NOTE: the number of nonces is v = 2 here!
let sum_R = [
public_partial_nonce[0].0[0] + public_partial_nonce[1].0[0],
public_partial_nonce[0].0[1] + public_partial_nonce[1].0[1],
public_partial_nonce[0].point1 + public_partial_nonce[1].point1,
public_partial_nonce[0].point2 + public_partial_nonce[1].point2,
];

// Compute b as hash of nonces
Expand All @@ -111,7 +111,7 @@ impl KeyPair {
// Compute effective nonce
// The idea is to compute R and r s.t. R = R_0 + b•R_1 and r = r_0 + b•r_1
let effective_R = sum_R[0] + b * sum_R[1];
let effective_r = private_partial_nonce.0[0] + b * private_partial_nonce.0[1];
let effective_r = private_partial_nonce.scalar1 + b * private_partial_nonce.scalar2;

// Compute Fiat-Shamir challenge of signature
let sig_challenge = Signature::k(&effective_R, &agg_public_key.agg_public_key, message);
Expand Down Expand Up @@ -146,7 +146,16 @@ impl KeyPair {
)
});
let R: [EdwardsPoint; 2] = r.map(|scalar| &scalar * constants::ED25519_BASEPOINT_TABLE);
(PrivatePartialNonces(r), PublicPartialNonces(R))
(
PrivatePartialNonces {
scalar1: r[0],
scalar2: r[1]
},
PublicPartialNonces {
point1:R[0],
point2: R[1]
}
)
}
}

Expand Down
50 changes: 19 additions & 31 deletions src/private_partial_nonces.rs
Original file line number Diff line number Diff line change
@@ -1,65 +1,53 @@
//! Module for private nonces
use std::fmt::Debug;
use crate::common::scalar_from_bytes;
use curve25519_dalek::scalar::Scalar;
use serde::{Deserialize, Serialize};
use zeroize::Zeroize;
use crate::public_partial_nonces::{PublicPartialNonces, PublicPartialNoncesBytes};

#[derive(Debug, PartialEq, Eq)]

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
/// Private Partial Nonces, they should be kept until partially signing a message and then they should be discarded.
///
/// SECURITY: Reusing them across signatures will cause the private key to leak
pub struct PrivatePartialNonces(pub(crate) [Scalar; 2]);

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PrivatePartialNoncesBytes(pub(crate) Vec<u8>);

impl Into<PrivatePartialNonces> for PrivatePartialNoncesBytes {
fn into(self) -> PrivatePartialNonces {
PrivatePartialNonces::deserialize(self.0).unwrap()
}
pub struct PrivatePartialNonces {
pub(crate) scalar1: Scalar,
pub(crate) scalar2: Scalar
}

impl From<PrivatePartialNonces> for PrivatePartialNoncesBytes {
fn from(value: PrivatePartialNonces) -> Self {
Self(value.serialize())
}
}
impl PrivatePartialNonces {
/// Serialize the private partial nonces for storage.
///
/// SECURITY: Do not reuse the nonces across signing instances. reusing the nonces will leak the private key.
pub fn serialize(&self) -> Vec<u8> {
pub fn serialize(&self) -> [u8; 64] {
let mut output = [0u8; 64];
output[..32].copy_from_slice(&self.0[0].to_bytes());
output[32..64].copy_from_slice(&self.0[1].to_bytes());
output.to_vec()
output[..32].copy_from_slice(&self.scalar1.to_bytes());
output[32..64].copy_from_slice(&self.scalar2.to_bytes());
output
}

/// Deserialize the private nonces,
/// Will return `None` if they're invalid.
pub fn deserialize(bytes: Vec<u8>) -> Option<Self> {
if bytes.len() != 64 {
return None
}

Some(Self([
scalar_from_bytes(&bytes[..32])?,
scalar_from_bytes(&bytes[32..64])?,
]))
pub fn deserialize(bytes: [u8; 64]) -> Option<Self> {
Some(Self{
scalar1: scalar_from_bytes(&bytes[..32])?,
scalar2: scalar_from_bytes(&bytes[32..64])?,
})
}
}

impl zeroize::ZeroizeOnDrop for PrivatePartialNonces {}

impl zeroize::Zeroize for PrivatePartialNonces {
fn zeroize(&mut self) {
self.0.zeroize()
self.scalar1.zeroize();
self.scalar2.zeroize();
}
}

impl Drop for PrivatePartialNonces {
fn drop(&mut self) {
self.0.zeroize();
self.scalar1.zeroize();
self.scalar2.zeroize();
}
}
43 changes: 12 additions & 31 deletions src/public_partial_nonces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,27 @@ use crate::common::edwards_from_bytes;


/// Public partial nonces, they should be transmitted to the other party in order to generate the aggregated nonce.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PublicPartialNonces(pub(crate) [EdwardsPoint; 2]);

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PublicPartialNoncesBytes(pub(crate) Vec<u8>);


impl Into<PublicPartialNonces> for PublicPartialNoncesBytes {
fn into(self) -> PublicPartialNonces {

PublicPartialNonces::deserialize(self.0).unwrap()
}
}

impl From<PublicPartialNonces> for PublicPartialNoncesBytes {

fn from(value: PublicPartialNonces) -> Self {
Self(value.serialize())
}
pub struct PublicPartialNonces{
pub(crate) point1: EdwardsPoint,
pub(crate) point2: EdwardsPoint
}

impl PublicPartialNonces {
/// Serialize the public partial nonces in order to transmit the other party.
pub fn serialize(&self) -> Vec<u8> {
pub fn serialize(&self) -> [u8; 64] {
let mut output = [0u8; 64];
output[..32].copy_from_slice(&self.0[0].compress().0[..]);
output[32..64].copy_from_slice(&self.0[1].compress().0[..]);
output.to_vec()
output[..32].copy_from_slice(&self.point1.compress().0[..]);
output[32..64].copy_from_slice(&self.point2.compress().0[..]);
output
}

/// Deserialize the public partial nonces.
pub fn deserialize(bytes: Vec<u8>) -> Option<Self> {
if bytes.len() != 64 {
return None
}

Some(Self([
edwards_from_bytes(&bytes[..32])?,
edwards_from_bytes(&bytes[32..64])?,
]))
pub fn deserialize(bytes: [u8; 64]) -> Option<Self> {
Some(Self {
point1: edwards_from_bytes(&bytes[..32])?,
point2: edwards_from_bytes(&bytes[32..64])?,
})
}
}

0 comments on commit 9f93c6a

Please sign in to comment.