Make it typesafe to hash only slices of 32 bytes

This commit is contained in:
Thomas Eizinger 2021-05-11 21:21:07 +10:00
parent 32cb801fc7
commit e5b59ee67e
No known key found for this signature in database
GPG Key ID: 651AC83A6C6C8B96
3 changed files with 62 additions and 71 deletions

View File

@ -13,7 +13,7 @@ const INV_EIGHT: Scalar = Scalar::from_bits([
]);
pub fn sign(
msg: &[u8],
msg: &[u8; 32],
signing_key: Scalar,
H_p_pk: EdwardsPoint,
alpha: Scalar,
@ -32,20 +32,10 @@ pub fn sign(
let commitment_ring = Ring::new(commitment_ring);
let mu_P = hash_to_scalar!(
b"CLSAG_agg_0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|| ring
|| commitment_ring
|| I
|| D_inv_8
|| pseudo_output_commitment
b"CLSAG_agg_0" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment
);
let mu_C = hash_to_scalar!(
b"CLSAG_agg_1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|| ring
|| commitment_ring
|| I
|| D_inv_8
|| pseudo_output_commitment
b"CLSAG_agg_1" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment
);
dbg!(hex::encode(mu_P.as_bytes()));
@ -55,13 +45,7 @@ pub fn sign(
let compute_ring_element = |L: EdwardsPoint, R: EdwardsPoint| {
hash_to_scalar!(
b"CLSAG_round\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|| ring
|| commitment_ring
|| pseudo_output_commitment
|| msg
|| L
|| R
b"CLSAG_round" || ring || commitment_ring || pseudo_output_commitment || msg || L || R
)
};
@ -123,7 +107,7 @@ pub fn verify(
responses,
..
}: &Signature,
msg: &[u8],
msg: &[u8; 32],
ring: &[EdwardsPoint; RING_SIZE],
commitment_ring: &[EdwardsPoint; RING_SIZE],
pseudo_output_commitment: EdwardsPoint,
@ -133,20 +117,10 @@ pub fn verify(
let D = D_inv_8 * Scalar::from(8u8);
let mu_P = hash_to_scalar!(
b"CLSAG_agg_0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|| ring
|| commitment_ring
|| I
|| D_inv_8
|| pseudo_output_commitment
b"CLSAG_agg_0" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment
);
let mu_C = hash_to_scalar!(
b"CLSAG_agg_1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|| ring
|| commitment_ring
|| I
|| D_inv_8
|| pseudo_output_commitment
b"CLSAG_agg_1" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment
);
let adjusted_commitment_ring = &commitment_ring - pseudo_output_commitment;
@ -167,7 +141,7 @@ pub fn verify(
let R_i = compute_R(h, mu_P, mu_C, *s_i, pk_i, I, D);
h = hash_to_scalar!(
b"CLSAG_round\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
b"CLSAG_round"
|| ring
|| commitment_ring
|| pseudo_output_commitment

View File

@ -11,7 +11,11 @@ macro_rules! hash_to_scalar {
let mut hasher = tiny_keccak::Keccak::v256();
$(
hasher.update($e.to_cow_bytes().as_ref());
let bytes_vec = $e.to_cow_bytes();
for el in bytes_vec {
hasher.update(el.as_ref());
}
)+
let mut hash = [0u8; 32];
@ -22,44 +26,53 @@ macro_rules! hash_to_scalar {
};
}
type CowBytes<'a> = Cow<'a, [u8]>;
type CowBytes<'a> = Cow<'a, [u8; 32]>;
pub(crate) trait ToCowBytes {
fn to_cow_bytes(&self) -> CowBytes<'_>;
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>>;
}
impl ToCowBytes for CompressedEdwardsY {
fn to_cow_bytes(&self) -> CowBytes<'_> {
CowBytes::Borrowed(self.0.as_ref())
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>> {
vec![CowBytes::Borrowed(&self.0)]
}
}
impl ToCowBytes for EdwardsPoint {
fn to_cow_bytes(&self) -> CowBytes<'_> {
CowBytes::Owned(self.compress().0.to_vec())
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>> {
vec![CowBytes::Owned(self.compress().0)]
}
}
impl ToCowBytes for Vec<u8> {
fn to_cow_bytes(&self) -> CowBytes<'_> {
CowBytes::Borrowed(self.as_ref())
impl ToCowBytes for [u8; 32] {
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>> {
vec![CowBytes::Borrowed(&self)]
}
}
impl<const N: usize> ToCowBytes for [u8; N] {
fn to_cow_bytes(&self) -> CowBytes<'_> {
CowBytes::Borrowed(self.as_ref())
}
}
impl ToCowBytes for [u8; 11] {
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>> {
let mut bytes = [0u8; 32];
bytes[0..11].copy_from_slice(self);
impl ToCowBytes for &[u8] {
fn to_cow_bytes(&self) -> CowBytes<'_> {
CowBytes::Borrowed(self)
vec![CowBytes::Owned(bytes)]
}
}
impl<'a> ToCowBytes for Ring<'a> {
fn to_cow_bytes(&self) -> CowBytes<'_> {
CowBytes::Borrowed(self.as_ref())
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>> {
vec![
CowBytes::Owned(self[0].compress().0),
CowBytes::Owned(self[1].compress().0),
CowBytes::Owned(self[2].compress().0),
CowBytes::Owned(self[3].compress().0),
CowBytes::Owned(self[4].compress().0),
CowBytes::Owned(self[5].compress().0),
CowBytes::Owned(self[6].compress().0),
CowBytes::Owned(self[7].compress().0),
CowBytes::Owned(self[8].compress().0),
CowBytes::Owned(self[9].compress().0),
CowBytes::Owned(self[10].compress().0),
]
}
}

View File

@ -145,10 +145,11 @@ async fn monerod_integration_test() {
let ecdh_key_1 = PrivateKey::random(&mut rng);
let (ecdh_info_1, out_blinding_1) = EcdhInfo::new_bulletproof(spend_amount, ecdh_key_1.scalar);
let (bulletproof, out_pk) = monero::make_bulletproof(&mut rng, &[spend_amount, 0], &[
out_blinding_0,
out_blinding_1,
])
let (bulletproof, out_pk) = monero::make_bulletproof(
&mut rng,
&[spend_amount, 0],
&[out_blinding_0, out_blinding_1],
)
.unwrap();
let k_image = {
@ -346,18 +347,21 @@ mod tests {
let relative_offsets = to_relative_offsets(&key_offsets);
assert_eq!(&relative_offsets, &[
VarInt(78),
VarInt(3),
VarInt(10),
VarInt(0),
VarInt(5),
VarInt(2),
VarInt(3),
VarInt(11),
VarInt(1),
VarInt(1),
VarInt(3),
])
assert_eq!(
&relative_offsets,
&[
VarInt(78),
VarInt(3),
VarInt(10),
VarInt(0),
VarInt(5),
VarInt(2),
VarInt(3),
VarInt(11),
VarInt(1),
VarInt(1),
VarInt(3),
]
)
}
}