Skip to content

Commit 902546c

Browse files
authored
use new arith api (#5)
1 parent a0c34af commit 902546c

File tree

6 files changed

+114
-30
lines changed

6 files changed

+114
-30
lines changed

Cargo.lock

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

k256/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ sha2 = { version = "=0.11.0-pre.4", optional = true, default-features = false }
3535
signature = { version = "=2.3.0-pre.4", optional = true }
3636

3737
[target.'cfg(all(target_os = "zkvm", target_arch = "riscv32"))'.dependencies]
38-
powdr-riscv-runtime = { git = "https://github.com/powdr-labs/powdr.git", tag = "v0.1.1", features = [
38+
powdr-riscv-runtime = { git = "https://github.com/powdr-labs/powdr.git", branch = "main", features = [
3939
"std",
4040
"getrandom",
4141
"allow_fake_rand",

k256/src/arithmetic/field.rs

+5
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ impl FieldElement {
122122
self.0.normalize().to_bytes_le()
123123
}
124124

125+
#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
126+
pub fn write_bytes_le(&self, out: &mut [u8; 32]) {
127+
self.0.normalize().write_bytes_le(out);
128+
}
129+
125130
/// Convert a `i64` to a field element.
126131
/// Returned value may be only weakly normalized.
127132
#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]

k256/src/arithmetic/field/field_8x32.rs

+5
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ impl FieldElement8x32 {
8383
self.0.to_le_byte_array()
8484
}
8585

86+
pub fn write_bytes_le(self, out: &mut [u8; 32]) {
87+
let bytes = self.0.to_le_byte_array();
88+
out.copy_from_slice(&bytes);
89+
}
90+
8691
/// Checks if the field element is greater or equal to the modulus.
8792
fn get_overflow(&self) -> Choice {
8893
let (_, carry) = self.0.adc(&MODULUS_CORRECTION, Limb(0));

k256/src/arithmetic/field/field_impl.rs

+6
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ impl FieldElementImpl {
110110
self.value.to_bytes_le()
111111
}
112112

113+
#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
114+
pub fn write_bytes_le(self, out: &mut [u8; 32]) {
115+
debug_assert!(self.normalized);
116+
self.value.write_bytes_le(out)
117+
}
118+
113119
pub fn normalize_weak(&self) -> Self {
114120
Self::new_weak_normalized(&self.value.normalize_weak())
115121
}

k256/src/arithmetic/projective.rs

+93-25
Original file line numberDiff line numberDiff line change
@@ -101,21 +101,46 @@ impl ProjectivePoint {
101101
{
102102
// call when the values are normalized, into powdr ec operations
103103
if self.z == FieldElement::ONE && other.z == FieldElement::ONE {
104-
// z being ONE means value is not identity
105-
let self_x: [u8; 32] = self.x.to_bytes_le().into();
106-
let self_y: [u8; 32] = self.y.to_bytes_le().into();
107-
let other_x: [u8; 32] = other.x.to_bytes_le().into();
108-
let other_y: [u8; 32] = other.y.to_bytes_le().into();
104+
let mut combined_self: [u8; 64] = [0; 64];
105+
let mut combined_other: [u8; 64] = [0; 64];
109106

110-
let (res_x, res_y) = if self_x == other_x && self_y == other_y {
111-
double_u8_le(self_x, self_y)
107+
// z being ONE means value is not identity
108+
self.x.write_bytes_le(
109+
(&mut combined_self[..32])
110+
.try_into()
111+
.expect("Expected 32 bytes"),
112+
);
113+
self.y.write_bytes_le(
114+
(&mut combined_self[32..])
115+
.try_into()
116+
.expect("Expected 32 bytes"),
117+
);
118+
119+
other.x.write_bytes_le(
120+
(&mut combined_other[..32])
121+
.try_into()
122+
.expect("Expected 32 bytes"),
123+
);
124+
other.y.write_bytes_le(
125+
(&mut combined_other[32..])
126+
.try_into()
127+
.expect("Expected 32 bytes"),
128+
);
129+
130+
let result = if combined_self == combined_other {
131+
double_u8_le(combined_self)
112132
} else {
113-
add_u8_le(self_x, self_y, other_x, other_y)
133+
add_u8_le(combined_self, combined_other)
114134
};
135+
let (res_x, res_y) = result.split_at(32);
115136

116137
let mut res = *self;
117-
res.x = FieldElement::from_bytes_unchecked_le(&res_x);
118-
res.y = FieldElement::from_bytes_unchecked_le(&res_y);
138+
res.x = FieldElement::from_bytes_unchecked_le(
139+
&res_x.try_into().expect("Expected 32 bytes"),
140+
);
141+
res.y = FieldElement::from_bytes_unchecked_le(
142+
&res_y.try_into().expect("Expected 32 bytes"),
143+
);
119144
return res;
120145
}
121146

@@ -203,21 +228,47 @@ impl ProjectivePoint {
203228
if other.is_identity().into() {
204229
return *self;
205230
} else if self.z == FieldElement::ONE {
206-
// z being ONE means value is not identity
207-
let self_x: [u8; 32] = self.x.to_bytes_le().into();
208-
let self_y: [u8; 32] = self.y.to_bytes_le().into();
209-
let other_x: [u8; 32] = other.x.to_bytes_le().into();
210-
let other_y: [u8; 32] = other.y.to_bytes_le().into();
231+
let mut combined_self: [u8; 64] = [0; 64];
232+
let mut combined_other: [u8; 64] = [0; 64];
211233

212-
let (res_x, res_y) = if self_x == other_x && self_y == other_y {
213-
double_u8_le(self_x, self_y)
234+
// z being ONE means value is not identity
235+
self.x.write_bytes_le(
236+
(&mut combined_self[..32])
237+
.try_into()
238+
.expect("Expected 32 bytes"),
239+
);
240+
self.y.write_bytes_le(
241+
(&mut combined_self[32..])
242+
.try_into()
243+
.expect("Expected 32 bytes"),
244+
);
245+
246+
other.x.write_bytes_le(
247+
(&mut combined_other[..32])
248+
.try_into()
249+
.expect("Expected 32 bytes"),
250+
);
251+
other.y.write_bytes_le(
252+
(&mut combined_other[32..])
253+
.try_into()
254+
.expect("Expected 32 bytes"),
255+
);
256+
257+
let result = if combined_self == combined_other {
258+
double_u8_le(combined_self)
214259
} else {
215-
add_u8_le(self_x, self_y, other_x, other_y)
260+
add_u8_le(combined_self, combined_other)
216261
};
217262

263+
let (res_x, res_y) = result.split_at(32);
264+
218265
let mut res = *self;
219-
res.x = FieldElement::from_bytes_unchecked_le(&res_x);
220-
res.y = FieldElement::from_bytes_unchecked_le(&res_y);
266+
res.x = FieldElement::from_bytes_unchecked_le(
267+
&res_x.try_into().expect("Expected 32 bytes"),
268+
);
269+
res.y = FieldElement::from_bytes_unchecked_le(
270+
&res_y.try_into().expect("Expected 32 bytes"),
271+
);
221272
return res;
222273
}
223274
}
@@ -292,13 +343,30 @@ impl ProjectivePoint {
292343
#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
293344
{
294345
if self.z == FieldElement::ONE {
346+
let mut combined_self: [u8; 64] = [0; 64];
347+
295348
// z being ONE means value is not identity
296-
let self_x: [u8; 32] = self.x.to_bytes_le().into();
297-
let self_y: [u8; 32] = self.y.to_bytes_le().into();
298-
let (res_x, res_y) = double_u8_le(self_x, self_y);
349+
self.x.write_bytes_le(
350+
(&mut combined_self[..32])
351+
.try_into()
352+
.expect("Expected 32 bytes"),
353+
);
354+
self.y.write_bytes_le(
355+
(&mut combined_self[32..])
356+
.try_into()
357+
.expect("Expected 32 bytes"),
358+
);
359+
360+
let result = double_u8_le(combined_self);
361+
let (res_x, res_y) = result.split_at(32);
362+
299363
let mut res = *self;
300-
res.x = FieldElement::from_bytes_unchecked_le(&res_x);
301-
res.y = FieldElement::from_bytes_unchecked_le(&res_y);
364+
res.x = FieldElement::from_bytes_unchecked_le(
365+
&res_x.try_into().expect("Expected 32 bytes"),
366+
);
367+
res.y = FieldElement::from_bytes_unchecked_le(
368+
&res_y.try_into().expect("Expected 32 bytes"),
369+
);
302370
return res;
303371
}
304372

0 commit comments

Comments
 (0)