Skip to content

Commit

Permalink
use new arith api (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardoalt authored Dec 17, 2024
1 parent a0c34af commit 902546c
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 30 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion k256/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ sha2 = { version = "=0.11.0-pre.4", optional = true, default-features = false }
signature = { version = "=2.3.0-pre.4", optional = true }

[target.'cfg(all(target_os = "zkvm", target_arch = "riscv32"))'.dependencies]
powdr-riscv-runtime = { git = "https://github.com/powdr-labs/powdr.git", tag = "v0.1.1", features = [
powdr-riscv-runtime = { git = "https://github.com/powdr-labs/powdr.git", branch = "main", features = [
"std",
"getrandom",
"allow_fake_rand",
Expand Down
5 changes: 5 additions & 0 deletions k256/src/arithmetic/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ impl FieldElement {
self.0.normalize().to_bytes_le()
}

#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
pub fn write_bytes_le(&self, out: &mut [u8; 32]) {
self.0.normalize().write_bytes_le(out);
}

/// Convert a `i64` to a field element.
/// Returned value may be only weakly normalized.
#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
Expand Down
5 changes: 5 additions & 0 deletions k256/src/arithmetic/field/field_8x32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ impl FieldElement8x32 {
self.0.to_le_byte_array()
}

pub fn write_bytes_le(self, out: &mut [u8; 32]) {
let bytes = self.0.to_le_byte_array();
out.copy_from_slice(&bytes);
}

/// Checks if the field element is greater or equal to the modulus.
fn get_overflow(&self) -> Choice {
let (_, carry) = self.0.adc(&MODULUS_CORRECTION, Limb(0));
Expand Down
6 changes: 6 additions & 0 deletions k256/src/arithmetic/field/field_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ impl FieldElementImpl {
self.value.to_bytes_le()
}

#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
pub fn write_bytes_le(self, out: &mut [u8; 32]) {
debug_assert!(self.normalized);
self.value.write_bytes_le(out)
}

pub fn normalize_weak(&self) -> Self {
Self::new_weak_normalized(&self.value.normalize_weak())
}
Expand Down
118 changes: 93 additions & 25 deletions k256/src/arithmetic/projective.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,46 @@ impl ProjectivePoint {
{
// call when the values are normalized, into powdr ec operations
if self.z == FieldElement::ONE && other.z == FieldElement::ONE {
// z being ONE means value is not identity
let self_x: [u8; 32] = self.x.to_bytes_le().into();
let self_y: [u8; 32] = self.y.to_bytes_le().into();
let other_x: [u8; 32] = other.x.to_bytes_le().into();
let other_y: [u8; 32] = other.y.to_bytes_le().into();
let mut combined_self: [u8; 64] = [0; 64];
let mut combined_other: [u8; 64] = [0; 64];

let (res_x, res_y) = if self_x == other_x && self_y == other_y {
double_u8_le(self_x, self_y)
// z being ONE means value is not identity
self.x.write_bytes_le(
(&mut combined_self[..32])
.try_into()
.expect("Expected 32 bytes"),
);
self.y.write_bytes_le(
(&mut combined_self[32..])
.try_into()
.expect("Expected 32 bytes"),
);

other.x.write_bytes_le(
(&mut combined_other[..32])
.try_into()
.expect("Expected 32 bytes"),
);
other.y.write_bytes_le(
(&mut combined_other[32..])
.try_into()
.expect("Expected 32 bytes"),
);

let result = if combined_self == combined_other {
double_u8_le(combined_self)
} else {
add_u8_le(self_x, self_y, other_x, other_y)
add_u8_le(combined_self, combined_other)
};
let (res_x, res_y) = result.split_at(32);

let mut res = *self;
res.x = FieldElement::from_bytes_unchecked_le(&res_x);
res.y = FieldElement::from_bytes_unchecked_le(&res_y);
res.x = FieldElement::from_bytes_unchecked_le(
&res_x.try_into().expect("Expected 32 bytes"),
);
res.y = FieldElement::from_bytes_unchecked_le(
&res_y.try_into().expect("Expected 32 bytes"),
);
return res;
}

Expand Down Expand Up @@ -203,21 +228,47 @@ impl ProjectivePoint {
if other.is_identity().into() {
return *self;
} else if self.z == FieldElement::ONE {
// z being ONE means value is not identity
let self_x: [u8; 32] = self.x.to_bytes_le().into();
let self_y: [u8; 32] = self.y.to_bytes_le().into();
let other_x: [u8; 32] = other.x.to_bytes_le().into();
let other_y: [u8; 32] = other.y.to_bytes_le().into();
let mut combined_self: [u8; 64] = [0; 64];
let mut combined_other: [u8; 64] = [0; 64];

let (res_x, res_y) = if self_x == other_x && self_y == other_y {
double_u8_le(self_x, self_y)
// z being ONE means value is not identity
self.x.write_bytes_le(
(&mut combined_self[..32])
.try_into()
.expect("Expected 32 bytes"),
);
self.y.write_bytes_le(
(&mut combined_self[32..])
.try_into()
.expect("Expected 32 bytes"),
);

other.x.write_bytes_le(
(&mut combined_other[..32])
.try_into()
.expect("Expected 32 bytes"),
);
other.y.write_bytes_le(
(&mut combined_other[32..])
.try_into()
.expect("Expected 32 bytes"),
);

let result = if combined_self == combined_other {
double_u8_le(combined_self)
} else {
add_u8_le(self_x, self_y, other_x, other_y)
add_u8_le(combined_self, combined_other)
};

let (res_x, res_y) = result.split_at(32);

let mut res = *self;
res.x = FieldElement::from_bytes_unchecked_le(&res_x);
res.y = FieldElement::from_bytes_unchecked_le(&res_y);
res.x = FieldElement::from_bytes_unchecked_le(
&res_x.try_into().expect("Expected 32 bytes"),
);
res.y = FieldElement::from_bytes_unchecked_le(
&res_y.try_into().expect("Expected 32 bytes"),
);
return res;
}
}
Expand Down Expand Up @@ -292,13 +343,30 @@ impl ProjectivePoint {
#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
{
if self.z == FieldElement::ONE {
let mut combined_self: [u8; 64] = [0; 64];

// z being ONE means value is not identity
let self_x: [u8; 32] = self.x.to_bytes_le().into();
let self_y: [u8; 32] = self.y.to_bytes_le().into();
let (res_x, res_y) = double_u8_le(self_x, self_y);
self.x.write_bytes_le(
(&mut combined_self[..32])
.try_into()
.expect("Expected 32 bytes"),
);
self.y.write_bytes_le(
(&mut combined_self[32..])
.try_into()
.expect("Expected 32 bytes"),
);

let result = double_u8_le(combined_self);
let (res_x, res_y) = result.split_at(32);

let mut res = *self;
res.x = FieldElement::from_bytes_unchecked_le(&res_x);
res.y = FieldElement::from_bytes_unchecked_le(&res_y);
res.x = FieldElement::from_bytes_unchecked_le(
&res_x.try_into().expect("Expected 32 bytes"),
);
res.y = FieldElement::from_bytes_unchecked_le(
&res_y.try_into().expect("Expected 32 bytes"),
);
return res;
}

Expand Down

0 comments on commit 902546c

Please sign in to comment.