Skip to content

Commit

Permalink
bigint2 acceleration update (#6)
Browse files Browse the repository at this point in the history
* WIP bigint2 impl

* reverse byteorder

* update to latest version

* loosen bytemuck version requirement

* update to rc version

* bump proc-macro2

* wip changes with extra checks

* uncomment ignored test

* put back precomputed tables logic

* point to risc0 2572

* bump to latest version and commit

* bump bigint2 commit to latest

* bump version to 1.2.0-rc.1

* swap pointers instead of copying data

* bump to 1.2

* Update k256/src/arithmetic/projective.rs

* Update k256/src/arithmetic/projective.rs

Co-authored-by: Frank Laub <[email protected]>

* Update k256/src/arithmetic/projective.rs

* Update k256/src/arithmetic/projective.rs

* Update k256/src/arithmetic/projective.rs

* remove dead code from bigint1

---------

Co-authored-by: Victor Graf <[email protected]>
Co-authored-by: Frank Laub <[email protected]>
  • Loading branch information
3 people committed Dec 11, 2024
1 parent 347e1e6 commit 68c60ba
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 71 deletions.
55 changes: 50 additions & 5 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions k256/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ serdect = { version = "0.2", optional = true, default-features = false }
sha2 = { version = "0.10", optional = true, default-features = false }
signature = { version = "2", optional = true }

[target.'cfg(all(target_os = "zkvm", target_arch = "riscv32"))'.dependencies]
risc0-bigint2 = { version = "1.2", features = ["unstable"] }
bytemuck = "1"

[dev-dependencies]
blobby = "0.3"
ecdsa-core = { version = "0.16", package = "ecdsa", default-features = false, features = ["dev"] }
Expand Down
59 changes: 59 additions & 0 deletions k256/src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,65 @@ pub(crate) const CURVE_EQUATION_B: FieldElement = FieldElement::from_bytes_unche
0, 0, 0, 0, 0, 0, 0, CURVE_EQUATION_B_SINGLE as u8,
]);

#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
use risc0_bigint2::ec;

#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
use ecdsa_core::elliptic_curve::group::prime::PrimeCurveAffine;

#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
pub(crate) fn affine_to_bigint2_affine(
affine: &AffinePoint,
) -> ec::AffinePoint<8, ec::Secp256k1Curve> {
if affine.is_identity().into() {
return ec::AffinePoint::IDENTITY;
}
let mut buffer = [[0u32; 8]; 2];
// TODO this could potentially read from internal repr (check risc0 felt endianness)
let mut x_bytes: [u8; 32] = affine.x.to_bytes().into();
let mut y_bytes: [u8; 32] = affine.y.to_bytes().into();
x_bytes.reverse();
y_bytes.reverse();

let x = bytemuck::cast::<_, [u32; 8]>(x_bytes);
let y = bytemuck::cast::<_, [u32; 8]>(y_bytes);
ec::AffinePoint::new_unchecked(x, y)
}

#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
pub(crate) fn projective_to_affine(p: &ProjectivePoint) -> ec::AffinePoint<8, ec::Secp256k1Curve> {
let aff = p.to_affine();
affine_to_bigint2_affine(&aff)
}

#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
pub(crate) fn affine_to_projective(
affine: &ec::AffinePoint<8, ec::Secp256k1Curve>,
) -> ProjectivePoint {
if let Some(value) = affine.as_u32s() {
let mut x = bytemuck::cast::<_, [u8; 32]>(value[0]);
let mut y = bytemuck::cast::<_, [u8; 32]>(value[1]);
x.reverse();
y.reverse();

crate::AffinePoint::new(
FieldElement::from_bytes_unchecked(&x),
FieldElement::from_bytes_unchecked(&y),
)
.into()
} else {
ProjectivePoint::IDENTITY
}
}

#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
pub(crate) fn scalar_to_words(s: &Scalar) -> [u32; 8] {
let mut bytes: [u8; 32] = s.to_bytes().into();
// U256 is big endian, need to flip to little endian.
bytes.reverse();
bytemuck::cast::<_, [u32; 8]>(bytes)
}

#[cfg(test)]
mod tests {
use super::CURVE_EQUATION_B;
Expand Down
38 changes: 38 additions & 0 deletions k256/src/arithmetic/mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,44 @@ impl LinearCombination<[(ProjectivePoint, Scalar)]> for ProjectivePoint {
}
}

#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
use risc0_bigint2::ec;

#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
use super::{affine_to_projective, projective_to_affine, scalar_to_words};

#[cfg(all(target_os = "zkvm", target_arch = "riscv32"))]
fn lincomb(
xks: &[(ProjectivePoint, Scalar)],
tables: &mut [(LookupTable, LookupTable)],
digits: &mut [(Radix16Decomposition<33>, Radix16Decomposition<33>)],
) -> ProjectivePoint {
let mut xks_iter = xks
.iter()
.map(|(p, s)| (projective_to_affine(p), scalar_to_words(s)));
let Some((affine, scalar)) = xks_iter.next() else {
return ProjectivePoint::IDENTITY;
};

let mut result = ec::AffinePoint::new_unchecked([0u32; 8], [0u32; 8]);
affine.mul(&scalar, &mut result);
let mut buffer = ec::AffinePoint::new_unchecked([0u32; 8], [0u32; 8]);
let mut mul_buffer = ec::AffinePoint::new_unchecked([0u32; 8], [0u32; 8]);

let mut result_ptr = &mut result;
let mut buffer_ptr = &mut buffer;

for (point, scalar) in xks_iter {
point.mul(&scalar, &mut mul_buffer);
result_ptr.add(&mul_buffer, &mut buffer_ptr);
core::mem::swap(&mut result_ptr, &mut buffer_ptr);
}

// Convert the final result back to projective form
affine_to_projective(result_ptr)
}

#[cfg(not(all(target_os = "zkvm", target_arch = "riscv32")))]
fn lincomb(
xks: &[(ProjectivePoint, Scalar)],
tables: &mut [(LookupTable, LookupTable)],
Expand Down
Loading

0 comments on commit 68c60ba

Please sign in to comment.