Correct discrepancies with the IETF draft

While all the transcript/extension code works as expected, which means, 
they don't cause any conflicts, n was still capped at u64::MAX at 
creation when it needs to be u16. Furthermore, participant index and 
scalars/points were little endian instead of big endian/curve dependent.
This commit is contained in:
Luke Parker
2022-05-06 07:49:18 -04:00
parent b443747994
commit 3dab26cd94
7 changed files with 32 additions and 35 deletions

View File

@@ -162,7 +162,7 @@ impl Algorithm<Ed25519> for Multisig {
// Given this is guaranteed to match commitments, which FROST commits to, this also technically
// doesn't need to be committed to if a canonical serialization is guaranteed
// It, again, doesn't hurt to include and ensures security boundaries are well formed
self.transcript.append_message(b"participant", &u64::try_from(l).unwrap().to_le_bytes());
self.transcript.append_message(b"participant", &u16::try_from(l).unwrap().to_be_bytes());
self.transcript.append_message(b"commitments_H", &serialized[0 .. 64]);
#[allow(non_snake_case)]

View File

@@ -77,15 +77,14 @@ impl Curve for Ed25519 {
32
}
fn F_from_le_slice(slice: &[u8]) -> Result<Self::F, CurveError> {
fn F_from_slice(slice: &[u8]) -> Result<Self::F, CurveError> {
let scalar = Self::F::from_repr(
slice.try_into().map_err(|_| CurveError::InvalidLength(32, slice.len()))?
);
if scalar.is_some().unwrap_u8() == 1 {
Ok(scalar.unwrap())
} else {
Err(CurveError::InvalidScalar)
if scalar.is_some().unwrap_u8() == 0 {
Err(CurveError::InvalidScalar)?;
}
Ok(scalar.unwrap())
}
fn G_from_slice(slice: &[u8]) -> Result<Self::G, CurveError> {
@@ -105,7 +104,7 @@ impl Curve for Ed25519 {
}
}
fn F_to_le_bytes(f: &Self::F) -> Vec<u8> {
fn F_to_bytes(f: &Self::F) -> Vec<u8> {
f.to_repr().to_vec()
}

View File

@@ -64,6 +64,8 @@ impl SignableTransaction {
// These outputs can only be spent once. Therefore, it forces all RNGs derived from this
// transcript (such as the one used to create one time keys) to be unique
transcript.append_message(b"input_hash", &input.tx.0);
// TODO: Should this be u8, u16, or u32? Right now, outputs are solely up to 16, but what
// about the future?
transcript.append_message(b"input_output_index", &u64::try_from(input.o).unwrap().to_le_bytes());
// Not including this, with a doxxed list of payments, would allow brute forcing the inputs
// to determine RNG seeds and therefore the true spends