From 21c773413e49cd7a47773b54fc2991a4502466de Mon Sep 17 00:00:00 2001 From: Pavel Nikolov Date: Thu, 1 Aug 2024 17:43:14 +0300 Subject: [PATCH] add elliptic curve example --- Cargo.lock | 258 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 7 +- src/elliptic_curve.rs | 92 +++++++++++++++ 3 files changed, 356 insertions(+), 1 deletion(-) create mode 100644 src/elliptic_curve.rs diff --git a/Cargo.lock b/Cargo.lock index 4591a7a..bfcb81d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,18 +139,39 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bytes" version = "1.6.1" @@ -169,12 +190,104 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + [[package]] name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -197,6 +310,16 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -248,6 +371,17 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -265,6 +399,17 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + [[package]] name = "h2" version = "0.4.5" @@ -314,6 +459,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "http" version = "1.1.0" @@ -449,6 +603,20 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + [[package]] name = "libc" version = "0.2.155" @@ -613,6 +781,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -759,6 +937,16 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -784,6 +972,20 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "serde" version = "1.0.204" @@ -804,6 +1006,27 @@ dependencies = [ "syn", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "slab" version = "0.4.9" @@ -829,6 +1052,22 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.71" @@ -1028,6 +1267,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-ident" version = "1.0.12" @@ -1043,6 +1288,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "want" version = "0.3.1" @@ -1197,11 +1448,18 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + [[package]] name = "zkp-auth" version = "0.1.0" dependencies = [ "hex", + "k256", "num-bigint", "num-traits", "prost", diff --git a/Cargo.toml b/Cargo.toml index dc9fe3f..5078f15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,8 +12,12 @@ path = "src/server.rs" name = "zkpauth-client" path = "src/client.rs" +[[bin]] # Bin to demonstrate the Elliptic curve example +name = "ec-example" +path = "src/elliptic_curve.rs" + [dependencies] -num-bigint = {version = "0.4.6", features = ["rand"]} +num-bigint = { version = "0.4.6", features = ["rand"] } num-traits = "0.2" prost = "0.13" rand = "0.8.5" @@ -21,6 +25,7 @@ hex = "0.4" tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } tonic = "0.12" uuid = { version = "1", features = ["v4"] } +k256 = "0.13.3" [build-dependencies] tonic-build = "0.12" diff --git a/src/elliptic_curve.rs b/src/elliptic_curve.rs new file mode 100644 index 0000000..c5ccab2 --- /dev/null +++ b/src/elliptic_curve.rs @@ -0,0 +1,92 @@ +use k256::elliptic_curve::{sec1::ToEncodedPoint, Field}; +use k256::{ProjectivePoint, Scalar}; +use rand::rngs::OsRng; + +fn main() { + // Generate a random private key for the prover + let mut rng = OsRng; + let sk = Scalar::random(&mut rng); + let pk = ProjectivePoint::GENERATOR * sk; + + // Prover generates a random nonce + let nonce = Scalar::random(&mut rng); + let r = ProjectivePoint::GENERATOR * nonce; + + // Prover sends the commitment (r) to the verifier + println!("Prover sends r: {:?}", r.to_encoded_point(false)); + + // Verifier generates a random challenge + let challenge = Scalar::random(&mut rng); + println!("Verifier sends challenge: {:?}", challenge); + + // Prover computes the response + let response = nonce + challenge * sk; + println!("Prover sends response: {:?}", response); + + // Verifier computes r' = response * G - challenge * pk + let computed_r = ProjectivePoint::GENERATOR * response - pk * challenge; + println!("Verifier computes r': {:?}", computed_r.to_encoded_point(false)); + + // Verifier checks if r' == r + let valid = computed_r.to_affine().eq(&r.to_affine()); + println!("Verification result: {:?}", valid); +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_zkp_authentication() { + // Generate a random private key for the prover + let mut rng = OsRng; + let sk = Scalar::random(&mut rng); + let pk = ProjectivePoint::GENERATOR * sk; + + // Prover generates a random nonce + let nonce = Scalar::random(&mut rng); + let r = ProjectivePoint::GENERATOR * nonce; + + // Verifier generates a random challenge + let challenge = Scalar::random(&mut rng); + + // Prover computes the response + let response = nonce + challenge * sk; + + // Verifier computes r' = response * G - challenge * pk + let computed_r = ProjectivePoint::GENERATOR * response - pk * challenge; + + // Verifier checks if r' == r + let valid = computed_r.to_affine().eq(&r.to_affine()); + + // Assert that the verification is successful + assert!(valid); + } + + #[test] + fn test_invalid_proof() { + // Generate a random private key for the prover + let mut rng = OsRng; + let sk = Scalar::random(&mut rng); + let pk = ProjectivePoint::GENERATOR * sk; + + // Prover generates a random nonce + let nonce = Scalar::random(&mut rng); + let r = ProjectivePoint::GENERATOR * nonce; + + // Verifier generates a random challenge + let challenge = Scalar::random(&mut rng); + + // Prover computes an incorrect response + let response = nonce + challenge * (sk + Scalar::ONE); // Intentionally incorrect + + // Verifier computes r' = response * G - challenge * pk + let computed_r = ProjectivePoint::GENERATOR * response - pk * challenge; + + // Verifier checks if r' == r + let valid = computed_r.to_affine().eq(&r.to_affine()); + + // Assert that the verification fails + assert!(!valid); + } +}