Skip to content

Commit fd89aa9

Browse files
committed
MSM Straus implementation
1 parent d47acbd commit fd89aa9

File tree

19 files changed

+849
-16
lines changed

19 files changed

+849
-16
lines changed

.github/workflows/backend-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ jobs:
7979
- backend: zkcrypto
8080
support_wasm: true
8181
support_ckzg: true
82-
clippy-flag: --all-features
82+
clippy-flag: --features=default,std,rand,parallel
8383
- backend: arkworks4
8484
support_wasm: true
8585
support_ckzg: true

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

arkworks4/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ wbits = [
5151
arkmsm = [
5252
"kzg/arkmsm"
5353
]
54+
strauss = [
55+
"kzg/strauss"
56+
]
5457
c_bindings = []
5558
diskcache = [
5659
"kzg/diskcache"

arkworks5/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ arkmsm = [
5151
wbits = [
5252
"kzg/wbits"
5353
]
54+
strauss = [
55+
"kzg/strauss"
56+
]
5457
c_bindings = []
5558
diskcache = [
5659
"kzg/diskcache"

blst/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ sppark = [
5454
wbits = [
5555
"kzg/wbits"
5656
]
57+
strauss = [
58+
"kzg/strauss"
59+
]
5760
c_bindings = []
5861
diskcache = [
5962
"kzg/diskcache"

constantine/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ arbitrary = "1.4.2"
2121
criterion = "0.5.1"
2222
kzg-bench = { path = "../kzg-bench" }
2323
rand = "0.8.5"
24+
rust-kzg-blst = { path = "../blst", default-features = false, features = ["std", "rand"] }
2425

2526
[features]
2627
default = [
@@ -52,7 +53,13 @@ arkmsm = [
5253
wbits = [
5354
"kzg/wbits"
5455
]
56+
strauss = [
57+
"kzg/strauss"
58+
]
5559
c_bindings = []
60+
diskcache = [
61+
"kzg/diskcache"
62+
]
5663

5764
[[bench]]
5865
name = "das"

constantine/src/types/g1.rs

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,11 +458,91 @@ impl G1Affine<CtG1, CtFp> for CtG1Affine {
458458
}
459459

460460
fn to_bytes_uncompressed(&self) -> [u8; 96] {
461-
todo!()
461+
let mut out = [0u8; 96];
462+
463+
// Check if point is infinity
464+
if self.is_infinity() {
465+
// Set infinity flag (bit 6) in first byte
466+
out[0] = 0x40;
467+
return out;
468+
}
469+
470+
// Serialize: 48 bytes x (big-endian) || 48 bytes y (big-endian)
471+
// limbs are stored in little-endian, so limbs[5] is most significant
472+
for i in 0..6 {
473+
let bytes = self.0.x.limbs[5 - i].to_be_bytes();
474+
out[i * 8..(i + 1) * 8].copy_from_slice(&bytes);
475+
}
476+
for i in 0..6 {
477+
let bytes = self.0.y.limbs[5 - i].to_be_bytes();
478+
out[48 + i * 8..48 + (i + 1) * 8].copy_from_slice(&bytes);
479+
}
480+
481+
out
462482
}
463483

464-
fn from_bytes_uncompressed(_bytes: [u8; 96]) -> Result<Self, String> {
465-
todo!()
484+
fn from_bytes_uncompressed(bytes: [u8; 96]) -> Result<Self, String> {
485+
// Check flags in first byte
486+
let compression_flag = bytes[0] & 0x80; // most-significant bit
487+
let infinity_flag = bytes[0] & 0x40; // second most-significant bit
488+
let sort_flag = bytes[0] & 0x20; // third most-significant bit
489+
490+
// For uncompressed, compression bit must be 0
491+
if compression_flag != 0 {
492+
return Err("Compression flag set for uncompressed encoding".to_string());
493+
}
494+
495+
// Sort flag must be 0 for uncompressed
496+
if sort_flag != 0 {
497+
return Err("Sort flag must be 0 for uncompressed encoding".to_string());
498+
}
499+
500+
// Handle infinity point
501+
if infinity_flag != 0 {
502+
// All other bits (except flags) must be zero for infinity
503+
if bytes[0] & 0x1f != 0 || bytes[1..].iter().any(|&b| b != 0) {
504+
return Err("Invalid infinity encoding".to_string());
505+
}
506+
return Ok(Self::zero());
507+
}
508+
509+
let mut x_limbs: [usize; 6] = [0; 6];
510+
let mut y_limbs: [usize; 6] = [0; 6];
511+
512+
// Deserialize: bytes come in big-endian
513+
// We need to store them in little-endian limbs array
514+
// First limb needs to have flag bits cleared
515+
for i in 0..6 {
516+
let mut limb_bytes = [0u8; 8];
517+
limb_bytes.copy_from_slice(&bytes[i * 8..(i + 1) * 8]);
518+
let mut limb_value = usize::from_be_bytes(limb_bytes);
519+
// Clear top 3 flag bits from the first limb (most significant)
520+
if i == 0 {
521+
limb_value &= 0x1fffffffffffffff; // Clear bits 63, 62, 61
522+
}
523+
x_limbs[5 - i] = limb_value;
524+
}
525+
for i in 0..6 {
526+
let mut limb_bytes = [0u8; 8];
527+
limb_bytes.copy_from_slice(&bytes[48 + i * 8..48 + (i + 1) * 8]);
528+
y_limbs[5 - i] = usize::from_be_bytes(limb_bytes);
529+
}
530+
531+
let tmp = bls12_381_g1_aff {
532+
x: bls12_381_fp { limbs: x_limbs },
533+
y: bls12_381_fp { limbs: y_limbs },
534+
};
535+
536+
// Validate point is on curve
537+
unsafe {
538+
match constantine::ctt_bls12_381_validate_g1(&tmp) {
539+
ctt_codec_ecc_status::cttCodecEcc_Success => Ok(CtG1Affine(tmp)),
540+
ctt_codec_ecc_status::cttCodecEcc_PointAtInfinity => {
541+
Err("Point at infinity should have infinity flag set".to_string())
542+
}
543+
_ => Err("Point is not on the curve".to_string()),
544+
}
545+
}
466546
}
467547
}
468548

constantine/tests/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
pub mod local_tests;
2+
3+
mod serialization;

0 commit comments

Comments
 (0)