Skip to content

Commit 385adda

Browse files
committed
add support for RISC Zero cryptographic accelerators
1 parent 5312a03 commit 385adda

File tree

14 files changed

+4430
-39
lines changed

14 files changed

+4430
-39
lines changed

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,10 @@ resolver = "2"
1010
[profile.dev]
1111
opt-level = 2
1212

13+
[patch.crates-io.crypto-bigint]
14+
git = "https://github.com/risc0/RustCrypto-crypto-bigint"
15+
tag = "v0.5.5-risczero.0"
16+
17+
[patch.crates-io.sha2]
18+
git = "https://github.com/risc0/RustCrypto-hashes"
19+
tag = "sha2-v0.10.8-risczero.0"

curve25519-dalek/Cargo.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ features = ["serde", "rand_core", "digest", "legacy_compatibility", "group-bits"
3232
[dev-dependencies]
3333
sha2 = { version = "0.10", default-features = false }
3434
bincode = "1"
35-
criterion = { version = "0.5", features = ["html_reports"] }
36-
hex = "0.4.2"
3735
rand = "0.8"
3836
rand_core = { version = "0.6", default-features = false, features = ["getrandom"] }
3937

@@ -49,18 +47,26 @@ required-features = ["alloc", "rand_core"]
4947
cfg-if = "1"
5048
ff = { version = "0.13", default-features = false, optional = true }
5149
group = { version = "0.13", default-features = false, optional = true }
50+
hex = "0.4.2"
5251
rand_core = { version = "0.6.4", default-features = false, optional = true }
5352
digest = { version = "0.10", default-features = false, optional = true }
5453
subtle = { version = "2.3.0", default-features = false }
5554
serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] }
5655
zeroize = { version = "1", default-features = false, optional = true }
5756

57+
[target.'cfg(target_os = "zkvm")'.dependencies]
58+
# Use crypto-bigint v0.5.5, which is overridden with a patch for RISC Zero acceleration.
59+
crypto-bigint = { version = "=0.5.5", default-features = false, features = ["zeroize"] }
60+
5861
[target.'cfg(target_arch = "x86_64")'.dependencies]
5962
cpufeatures = "0.2.6"
6063

6164
[target.'cfg(curve25519_dalek_backend = "fiat")'.dependencies]
6265
fiat-crypto = { version = "0.2.1", default-features = false }
6366

67+
[target.'cfg(not(target_os = "zkvm"))'.dev-dependencies]
68+
criterion = { version = "0.5.1", features = ["html_reports"] }
69+
6470
[features]
6571
default = ["alloc", "precomputed-tables", "zeroize"]
6672
alloc = ["zeroize?/alloc"]

curve25519-dalek/src/backend/serial/curve_models/mod.rs

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -383,13 +383,25 @@ impl ProjectivePoint {
383383
let XX = self.X.square();
384384
let YY = self.Y.square();
385385
let ZZ2 = self.Z.square2();
386-
let X_plus_Y = &self.X + &self.Y;
387-
let X_plus_Y_sq = X_plus_Y.square();
388386
let YY_plus_XX = &YY + &XX;
389387
let YY_minus_XX = &YY - &XX;
390388

389+
cfg_if::cfg_if! {
390+
if #[cfg(all(target_os = "zkvm", target_arch = "riscv32"))] {
391+
// According to https://en.wikipedia.org/wiki/Edwards_curve#Doubling,
392+
// (x + y)^2 - x^2 - y^2 is used as an optimization for computing 2xy.
393+
// However, multiplication is faster inside the zkvm so we compute
394+
// 2xy directly instead.
395+
let new_x = &(&FieldElement::TWO * &self.X) * &self.Y;
396+
} else {
397+
let X_plus_Y = &self.X + &self.Y;
398+
let X_plus_Y_sq = X_plus_Y.square();
399+
let new_x = &X_plus_Y_sq - &YY_plus_XX;
400+
}
401+
}
402+
391403
CompletedPoint {
392-
X: &X_plus_Y_sq - &YY_plus_XX,
404+
X: new_x,
393405
Y: YY_plus_XX,
394406
Z: YY_minus_XX,
395407
T: &ZZ2 - &YY_minus_XX,
@@ -418,7 +430,14 @@ impl<'a, 'b> Add<&'b ProjectiveNielsPoint> for &'a EdwardsPoint {
418430
let MM = &Y_minus_X * &other.Y_minus_X;
419431
let TT2d = &self.T * &other.T2d;
420432
let ZZ = &self.Z * &other.Z;
421-
let ZZ2 = &ZZ + &ZZ;
433+
434+
cfg_if::cfg_if! {
435+
if #[cfg(all(target_os = "zkvm", target_arch = "riscv32"))] {
436+
let ZZ2 = &FieldElement::TWO * &ZZ;
437+
} else {
438+
let ZZ2 = &ZZ + &ZZ;
439+
}
440+
}
422441

423442
CompletedPoint {
424443
X: &PP - &MM,
@@ -440,7 +459,14 @@ impl<'a, 'b> Sub<&'b ProjectiveNielsPoint> for &'a EdwardsPoint {
440459
let MP = &Y_minus_X * &other.Y_plus_X;
441460
let TT2d = &self.T * &other.T2d;
442461
let ZZ = &self.Z * &other.Z;
443-
let ZZ2 = &ZZ + &ZZ;
462+
463+
cfg_if::cfg_if! {
464+
if #[cfg(all(target_os = "zkvm", target_arch = "riscv32"))] {
465+
let ZZ2 = &FieldElement::TWO * &ZZ;
466+
} else {
467+
let ZZ2 = &ZZ + &ZZ;
468+
}
469+
}
444470

445471
CompletedPoint {
446472
X: &PM - &MP,
@@ -461,7 +487,14 @@ impl<'a, 'b> Add<&'b AffineNielsPoint> for &'a EdwardsPoint {
461487
let PP = &Y_plus_X * &other.y_plus_x;
462488
let MM = &Y_minus_X * &other.y_minus_x;
463489
let Txy2d = &self.T * &other.xy2d;
464-
let Z2 = &self.Z + &self.Z;
490+
491+
cfg_if::cfg_if! {
492+
if #[cfg(all(target_os = "zkvm", target_arch = "riscv32"))] {
493+
let Z2 = &FieldElement::TWO * &self.Z;
494+
} else {
495+
let Z2 = &self.Z + &self.Z;
496+
}
497+
}
465498

466499
CompletedPoint {
467500
X: &PP - &MM,
@@ -482,7 +515,14 @@ impl<'a, 'b> Sub<&'b AffineNielsPoint> for &'a EdwardsPoint {
482515
let PM = &Y_plus_X * &other.y_minus_x;
483516
let MP = &Y_minus_X * &other.y_plus_x;
484517
let Txy2d = &self.T * &other.xy2d;
485-
let Z2 = &self.Z + &self.Z;
518+
519+
cfg_if::cfg_if! {
520+
if #[cfg(all(target_os = "zkvm", target_arch = "riscv32"))] {
521+
let Z2 = &FieldElement::TWO * &self.Z;
522+
} else {
523+
let Z2 = &self.Z + &self.Z;
524+
}
525+
}
486526

487527
CompletedPoint {
488528
X: &PM - &MP,

curve25519-dalek/src/backend/serial/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ cfg_if! {
3131
#[doc(hidden)]
3232
pub mod fiat_u64;
3333

34+
} else if #[cfg(all(target_os = "zkvm", target_arch = "riscv32"))] {
35+
36+
pub mod risc0;
37+
3438
} else {
3539

3640
#[cfg(curve25519_dalek_bits = "32")]

0 commit comments

Comments
 (0)