mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-03 17:40:34 +00:00
Remove "as", except for floats as needed
Also updates Bulletproofs from C to not be length prefixed, yet rather have Rust calculate their length. Corrects an error in key_gen where self was blamed, instead of the faulty participant.
This commit is contained in:
parent
614badfef7
commit
ce4c899422
10 changed files with 38 additions and 24 deletions
|
@ -62,10 +62,8 @@ extern "C" {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
binary_archive<true> ba(ss);
|
binary_archive<true> ba(ss);
|
||||||
::serialization::serialize(ba, bp);
|
::serialization::serialize(ba, bp);
|
||||||
uint8_t* res = (uint8_t*) calloc(2 + ss.str().size(), 1); // malloc would also work
|
uint8_t* res = (uint8_t*) calloc(ss.str().size(), 1); // malloc would also work
|
||||||
memcpy(res + 2, ss.str().data(), ss.str().size());
|
memcpy(res, ss.str().data(), ss.str().size());
|
||||||
res[0] = ss.str().size() >> 8;
|
|
||||||
res[1] = ss.str().size() & 255;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ impl Curve for Ed25519 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn id_len() -> u8 {
|
fn id_len() -> u8 {
|
||||||
Self::id().len() as u8
|
u8::try_from(Self::id().len()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generator() -> Self::G {
|
fn generator() -> Self::G {
|
||||||
|
|
|
@ -41,11 +41,18 @@ impl Bulletproofs {
|
||||||
fn c_generate_bp(seed: *const u8, len: u8, amounts: *const u64, masks: *const [u8; 32]) -> *const u8;
|
fn c_generate_bp(seed: *const u8, len: u8, amounts: *const u64, masks: *const [u8; 32]) -> *const u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ptr = c_generate_bp(seed.as_ptr(), outputs.len() as u8, amounts.as_ptr(), masks.as_ptr());
|
let ptr = c_generate_bp(
|
||||||
let len = ((ptr.read() as usize) << 8) + (ptr.add(1).read() as usize);
|
seed.as_ptr(),
|
||||||
|
u8::try_from(outputs.len()).unwrap(),
|
||||||
|
amounts.as_ptr(),
|
||||||
|
masks.as_ptr()
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut len = 6 * 32;
|
||||||
|
len += (2 * (1 + (usize::from(ptr.add(len).read()) * 32))) + (3 * 32);
|
||||||
res = Bulletproofs::deserialize(
|
res = Bulletproofs::deserialize(
|
||||||
// Wrap in a cursor to provide a mutable Reader
|
// Wrap in a cursor to provide a mutable Reader
|
||||||
&mut std::io::Cursor::new(std::slice::from_raw_parts(ptr.add(2), len))
|
&mut std::io::Cursor::new(std::slice::from_raw_parts(ptr, len))
|
||||||
).expect("Couldn't deserialize Bulletproofs from Monero");
|
).expect("Couldn't deserialize Bulletproofs from Monero");
|
||||||
free(ptr);
|
free(ptr);
|
||||||
};
|
};
|
||||||
|
@ -64,7 +71,7 @@ impl Bulletproofs {
|
||||||
let mut serialized = Vec::with_capacity((9 + (2 * self.L.len())) * 32);
|
let mut serialized = Vec::with_capacity((9 + (2 * self.L.len())) * 32);
|
||||||
self.serialize(&mut serialized).unwrap();
|
self.serialize(&mut serialized).unwrap();
|
||||||
let commitments: Vec<[u8; 32]> = commitments.iter().map(
|
let commitments: Vec<[u8; 32]> = commitments.iter().map(
|
||||||
|commitment| (commitment * Scalar::from(8 as u8).invert()).compress().to_bytes()
|
|commitment| (commitment * Scalar::from(8u8).invert()).compress().to_bytes()
|
||||||
).collect();
|
).collect();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -79,7 +86,13 @@ impl Bulletproofs {
|
||||||
) -> bool;
|
) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
c_verify_bp(seed.as_ptr(), serialized.len(), serialized.as_ptr(), commitments.len() as u8, commitments.as_ptr())
|
c_verify_bp(
|
||||||
|
seed.as_ptr(),
|
||||||
|
serialized.len(),
|
||||||
|
serialized.as_ptr(),
|
||||||
|
u8::try_from(commitments.len()).unwrap(),
|
||||||
|
commitments.as_ptr()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ mod multisig;
|
||||||
pub use multisig::{ClsagDetails, ClsagMultisig};
|
pub use multisig::{ClsagDetails, ClsagMultisig};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref INV_EIGHT: Scalar = Scalar::from(8 as u8).invert();
|
static ref INV_EIGHT: Scalar = Scalar::from(8u8).invert();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Error, Debug)]
|
#[derive(Clone, Error, Debug)]
|
||||||
|
@ -60,8 +60,9 @@ impl ClsagInput {
|
||||||
if n > u8::MAX.into() {
|
if n > u8::MAX.into() {
|
||||||
Err(ClsagError::InternalError("max ring size in this library is u8 max".to_string()))?;
|
Err(ClsagError::InternalError("max ring size in this library is u8 max".to_string()))?;
|
||||||
}
|
}
|
||||||
if decoys.i >= (n as u8) {
|
let n = u8::try_from(n).unwrap();
|
||||||
Err(ClsagError::InvalidRingMember(decoys.i, n as u8))?;
|
if decoys.i >= n {
|
||||||
|
Err(ClsagError::InvalidRingMember(decoys.i, n))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the commitment matches
|
// Validate the commitment matches
|
||||||
|
@ -123,13 +124,13 @@ fn core(
|
||||||
// mu_P with agg_0
|
// mu_P with agg_0
|
||||||
let mu_P = hash_to_scalar(&to_hash);
|
let mu_P = hash_to_scalar(&to_hash);
|
||||||
// mu_C with agg_1
|
// mu_C with agg_1
|
||||||
to_hash[AGG_0.len() - 1] = '1' as u8;
|
to_hash[AGG_0.len() - 1] = b'1';
|
||||||
let mu_C = hash_to_scalar(&to_hash);
|
let mu_C = hash_to_scalar(&to_hash);
|
||||||
|
|
||||||
// Truncate it for the round transcript, altering the DST as needed
|
// Truncate it for the round transcript, altering the DST as needed
|
||||||
to_hash.truncate(((2 * n) + 1) * 32);
|
to_hash.truncate(((2 * n) + 1) * 32);
|
||||||
for i in 0 .. ROUND.len() {
|
for i in 0 .. ROUND.len() {
|
||||||
to_hash[PREFIX.len() + i] = ROUND[i] as u8;
|
to_hash[PREFIX.len() + i] = ROUND[i];
|
||||||
}
|
}
|
||||||
// Unfortunately, it's I D pseudo_out instead of pseudo_out I D, meaning this needs to be
|
// Unfortunately, it's I D pseudo_out instead of pseudo_out I D, meaning this needs to be
|
||||||
// truncated just to add it back
|
// truncated just to add it back
|
||||||
|
@ -254,7 +255,7 @@ impl Clsag {
|
||||||
&nonce * &ED25519_BASEPOINT_TABLE,
|
&nonce * &ED25519_BASEPOINT_TABLE,
|
||||||
nonce * hash_to_point(&inputs[i].2.decoys.ring[usize::from(inputs[i].2.decoys.i)][0])
|
nonce * hash_to_point(&inputs[i].2.decoys.ring[usize::from(inputs[i].2.decoys.i)][0])
|
||||||
);
|
);
|
||||||
clsag.s[inputs[i].2.decoys.i as usize] = nonce - ((p * inputs[i].0) + c);
|
clsag.s[usize::from(inputs[i].2.decoys.i)] = nonce - ((p * inputs[i].0) + c);
|
||||||
|
|
||||||
res.push((clsag, pseudo_out));
|
res.push((clsag, pseudo_out));
|
||||||
}
|
}
|
||||||
|
@ -341,7 +342,8 @@ impl Clsag {
|
||||||
|
|
||||||
if c_verify_clsag(
|
if c_verify_clsag(
|
||||||
serialized.len(), serialized.as_ptr(),
|
serialized.len(), serialized.as_ptr(),
|
||||||
ring.len() as u8, ring_bytes.as_ptr(),
|
u8::try_from(ring.len()).map_err(|_| ClsagError::InternalError("too large ring".to_string()))?,
|
||||||
|
ring_bytes.as_ptr(),
|
||||||
I_bytes.as_ptr(), pseudo_out_bytes.as_ptr(), msg.as_ptr()
|
I_bytes.as_ptr(), pseudo_out_bytes.as_ptr(), msg.as_ptr()
|
||||||
) {
|
) {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub const VARINT_CONTINUATION_MASK: u8 = 0b1000_0000;
|
||||||
pub fn write_varint<W: io::Write>(varint: &u64, w: &mut W) -> io::Result<()> {
|
pub fn write_varint<W: io::Write>(varint: &u64, w: &mut W) -> io::Result<()> {
|
||||||
let mut varint = *varint;
|
let mut varint = *varint;
|
||||||
while {
|
while {
|
||||||
let mut b = (varint & u64::from(!VARINT_CONTINUATION_MASK)) as u8;
|
let mut b = u8::try_from(varint & u64::from(!VARINT_CONTINUATION_MASK)).unwrap();
|
||||||
varint >>= 7;
|
varint >>= 7;
|
||||||
if varint != 0 {
|
if varint != 0 {
|
||||||
b |= VARINT_CONTINUATION_MASK;
|
b |= VARINT_CONTINUATION_MASK;
|
||||||
|
|
|
@ -237,7 +237,7 @@ impl SignableTransaction {
|
||||||
PublicKey { point: self.outputs[0].R.compress() }
|
PublicKey { point: self.outputs[0].R.compress() }
|
||||||
).consensus_encode(&mut extra).unwrap();
|
).consensus_encode(&mut extra).unwrap();
|
||||||
SubField::AdditionalPublickKey(
|
SubField::AdditionalPublickKey(
|
||||||
self.outputs[1 .. self.outputs.len()].iter().map(|output| PublicKey { point: output.R.compress() }).collect()
|
self.outputs[1 ..].iter().map(|output| PublicKey { point: output.R.compress() }).collect()
|
||||||
).consensus_encode(&mut extra).unwrap();
|
).consensus_encode(&mut extra).unwrap();
|
||||||
|
|
||||||
// Format it for monero-rs
|
// Format it for monero-rs
|
||||||
|
|
|
@ -200,7 +200,7 @@ fn complete_r2<R: RngCore + CryptoRng, C: Curve>(
|
||||||
// Step 2. Verify each share
|
// Step 2. Verify each share
|
||||||
let mut shares = HashMap::new();
|
let mut shares = HashMap::new();
|
||||||
for (l, share) in serialized {
|
for (l, share) in serialized {
|
||||||
shares.insert(l, C::F_from_slice(&share).map_err(|_| FrostError::InvalidShare(params.i()))?);
|
shares.insert(l, C::F_from_slice(&share).map_err(|_| FrostError::InvalidShare(l))?);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the exponent for a given participant and apply it to a series of commitments
|
// Calculate the exponent for a given participant and apply it to a series of commitments
|
||||||
|
@ -240,6 +240,7 @@ fn complete_r2<R: RngCore + CryptoRng, C: Curve>(
|
||||||
// Stripe commitments per t and sum them in advance. Calculating verification shares relies on
|
// Stripe commitments per t and sum them in advance. Calculating verification shares relies on
|
||||||
// these sums so preprocessing them is a massive speedup
|
// these sums so preprocessing them is a massive speedup
|
||||||
// If these weren't just sums, yet the tables used in multiexp, this would be further optimized
|
// If these weren't just sums, yet the tables used in multiexp, this would be further optimized
|
||||||
|
// As of right now, each multiexp will regenerate them
|
||||||
let mut stripes = Vec::with_capacity(usize::from(params.t()));
|
let mut stripes = Vec::with_capacity(usize::from(params.t()));
|
||||||
for t in 0 .. usize::from(params.t()) {
|
for t in 0 .. usize::from(params.t()) {
|
||||||
stripes.push(commitments.values().map(|commitments| commitments[t]).sum());
|
stripes.push(commitments.values().map(|commitments| commitments[t]).sum());
|
||||||
|
|
|
@ -143,7 +143,7 @@ fn sign_with_share<C: Curve, A: Algorithm<C>>(
|
||||||
|
|
||||||
let commitments = commitments.remove(l).unwrap();
|
let commitments = commitments.remove(l).unwrap();
|
||||||
let mut read_commitment = |c, label| {
|
let mut read_commitment = |c, label| {
|
||||||
let commitment = &commitments[c .. c + C::G_len()];
|
let commitment = &commitments[c .. (c + C::G_len())];
|
||||||
transcript.append_message(label, commitment);
|
transcript.append_message(label, commitment);
|
||||||
C::G_from_slice(commitment).map_err(|_| FrostError::InvalidCommitment(*l))
|
C::G_from_slice(commitment).map_err(|_| FrostError::InvalidCommitment(*l))
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Curve for Secp256k1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn id_len() -> u8 {
|
fn id_len() -> u8 {
|
||||||
Self::id().len() as u8
|
u8::try_from(Self::id().len()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generator() -> Self::G {
|
fn generator() -> Self::G {
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub fn multiexp<
|
||||||
}
|
}
|
||||||
|
|
||||||
for s in 0 .. tables.len() {
|
for s in 0 .. tables.len() {
|
||||||
res += tables[s][nibbles[s][b] as usize];
|
res += tables[s][usize::from(nibbles[s][b])];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
|
@ -75,7 +75,7 @@ pub fn multiexp_vartime<
|
||||||
|
|
||||||
for s in 0 .. tables.len() {
|
for s in 0 .. tables.len() {
|
||||||
if nibbles[s][b] != 0 {
|
if nibbles[s][b] != 0 {
|
||||||
res += tables[s][nibbles[s][b] as usize];
|
res += tables[s][usize::from(nibbles[s][b])];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue