From 90fce7a7e0f79facce1a4c0ad93f831dae95b98c Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Wed, 29 Nov 2023 08:33:21 +0100 Subject: [PATCH 01/53] More ArkWorks stuff --- rust-src/Cargo.lock | 132 ++++++++++-------- rust-src/concordium_base/Cargo.toml | 9 +- .../benches/range_proof_bench.rs | 13 +- .../curve_arithmetic/arkworks_instances.rs | 128 +++++++---------- .../curve_arithmetic/ed25519_ng_instance.rs | 5 +- 5 files changed, 144 insertions(+), 143 deletions(-) diff --git a/rust-src/Cargo.lock b/rust-src/Cargo.lock index bde3a9762..45c3fefdc 100644 --- a/rust-src/Cargo.lock +++ b/rust-src/Cargo.lock @@ -87,41 +87,60 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + [[package]] name = "ark-ec" -version = "0.2.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56006994f509d76fbce6f6ffe3108f7191b4f3754ecd00bbae7cac20ec05020" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ "ark-ff", + "ark-poly", "ark-serialize", "ark-std", "derivative", + "hashbrown 0.13.2", + "itertools", "num-traits", "zeroize", ] [[package]] name = "ark-ff" -version = "0.2.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d8802d40fce9212c5c09be08f75c4b3becc0c488e87f60fff787b01250ce33" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ "ark-ff-asm", "ark-ff-macros", "ark-serialize", "ark-std", "derivative", + "digest 0.10.7", + "itertools", + "num-bigint 0.4.4", "num-traits", - "rustc_version 0.3.3", + "paste", + "rustc_version", "zeroize", ] [[package]] name = "ark-ff-asm" -version = "0.2.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e8cb28c2137af1ef058aa59616db3f7df67dbb70bf2be4ee6920008cc30d98c" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ "quote", "syn 1.0.109", @@ -129,33 +148,61 @@ dependencies = [ [[package]] name = "ark-ff-macros" -version = "0.2.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9c256a93a10ed9708c16a517d6dcfaba3d215c0d7fab44d29a9affefb5eeb8" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ "num-bigint 0.4.4", "num-traits", + "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + [[package]] name = "ark-serialize" -version = "0.2.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e9b59329dc9b92086b3dc619f31cef4a0c802f10829b575a3666d48a48387d" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ + "ark-serialize-derive", "ark-std", + "digest 0.10.7", + "num-bigint 0.4.4", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "ark-std" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5b856a29bea7b810858116a596beee3d20fc4c5aeb240e8e5a8bca4845a470" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ - "rand 0.7.3", - "rand_xorshift", + "num-traits", + "rand 0.8.5", ] [[package]] @@ -533,6 +580,7 @@ version = "3.2.0" dependencies = [ "aes", "anyhow", + "ark-bls12-381", "ark-ec", "ark-ff", "base64", @@ -806,7 +854,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.0", + "rustc_version", "syn 1.0.109", ] @@ -1525,6 +1573,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "pbkdf2" version = "0.10.1" @@ -1549,17 +1603,6 @@ dependencies = [ "sha2 0.10.7", ] -[[package]] -name = "pest" -version = "2.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - [[package]] name = "plotters" version = "0.3.5" @@ -1896,22 +1939,13 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.18", + "semver", ] [[package]] @@ -1954,30 +1988,12 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" version = "1.0.188" @@ -2297,12 +2313,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - [[package]] name = "unicode-ident" version = "1.0.11" diff --git a/rust-src/concordium_base/Cargo.toml b/rust-src/concordium_base/Cargo.toml index fecf7a495..6d130a16a 100644 --- a/rust-src/concordium_base/Cargo.toml +++ b/rust-src/concordium_base/Cargo.toml @@ -13,8 +13,9 @@ homepage = "https://github.com/Concordium/concordium-base" [dependencies] ff = "0.5" -ark-ff = "0.2" -ark-ec = "0.2" +ark-ff = "0.4" +ark-ec = "0.4" +ark-bls12-381 = "0.4.0" sha2 = "0.10" sha3 = "0.10" anyhow = "1.0" @@ -72,6 +73,10 @@ features = ["derive-serde"] version = "1" path = "../concordium_base_derive" +[patch.crates-io] +rand = { git = "https://github.com/rust-random/rand.git", tag = "0.8.5"} +# rand_core = { version = "0.6" } + [features] default = [] ffi = [] diff --git a/rust-src/concordium_base/benches/range_proof_bench.rs b/rust-src/concordium_base/benches/range_proof_bench.rs index 7129d75ab..8ab9ffd89 100644 --- a/rust-src/concordium_base/benches/range_proof_bench.rs +++ b/rust-src/concordium_base/benches/range_proof_bench.rs @@ -3,9 +3,18 @@ #[macro_use] extern crate criterion; +use ark_ec::{ + hashing::{ + curve_maps::wb::{WBConfig, WBMap}, + map_to_curve_hasher::MapToCurveBasedHasher, + HashToCurve, + }, + short_weierstrass::Projective, +}; +use ark_ff::field_hashers::DefaultFieldHasher; use concordium_base::{ bulletproofs::{range_proof::*, utils::Generators}, - curve_arithmetic::*, + curve_arithmetic::{arkworks_instances::ArkGroup, *}, id::id_proof_types::ProofVersion, pedersen_commitment::*, random_oracle::RandomOracle, @@ -126,6 +135,6 @@ criterion_group!( prove_verify_benchmarks::, prove_verify_benchmarks::, prove_verify_benchmarks::, - //prove_verify_benchmarks::> + //prove_verify_benchmarks::> ); criterion_main!(benchmarks); diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index e2ad90c65..ceb7c40f2 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -1,42 +1,31 @@ -use ark_ec::AffineCurve; -use ark_ff::{FpParameters, FromBytes}; +// use ark_ec::AffineCurve; +// use ark_ff::{FpParameters, FromBytes}; use core::fmt; +use ark_ff::BigInteger; + use crate::common::{Deserial, Serial}; use super::{Curve, CurveDecodingError, Field, GenericMultiExp, PrimeField}; #[derive(PartialEq, Eq, Copy, Clone, fmt::Debug)] -pub struct ArkField< - F: ark_ff::Field - + Sized - + Eq - + Copy - + Clone - + Send - + Sync - + fmt::Debug - + fmt::Display - + ark_ff::UniformRand, ->(F); - -impl Serial - for ArkField -{ +pub struct ArkField(F); + +impl From for ArkField { + fn from(value: F) -> Self { ArkField(value) } +} + +impl Serial for ArkField { fn serial(&self, _out: &mut B) { todo!() } } -impl - Deserial for ArkField -{ +impl Deserial for ArkField { fn deserial(_source: &mut R) -> crate::common::ParseResult { todo!() } } -impl - fmt::Display for ArkField -{ +impl fmt::Display for ArkField { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ::fmt(&self.0, f) } @@ -45,7 +34,7 @@ impl Field for ArkField { fn random(_rng: &mut R) -> Self { todo!() } - fn zero() -> Self { todo!() } + fn zero() -> Self { F::zero().into() } fn one() -> Self { todo!() } @@ -68,56 +57,41 @@ impl Field for ArkField { impl PrimeField for ArkField { const CAPACITY: u32 = Self::NUM_BITS - 1; - const NUM_BITS: u32 = F::Params::MODULUS_BITS; + const NUM_BITS: u32 = F::MODULUS_BIT_SIZE; fn into_repr(self) -> Vec { - // self.0.into_bigint().as_ref().to_vec() - self.0.into_repr().as_ref().to_vec() + self.0.into_bigint().as_ref().to_vec() + // self.0.into_repr().as_ref().to_vec() } fn from_repr(repr: &[u64]) -> Result { - let mut buffer = Vec::new(); - for u in repr { - buffer.extend(u.to_le_bytes()); - } - let big_int = F::BigInt::read(buffer.as_slice()) - .map_err(|_| CurveDecodingError::NotInField(format!("{:?}", repr)))?; - let res = - F::from_repr(big_int).ok_or(CurveDecodingError::NotInField(format!("{:?}", repr)))?; - Ok(ArkField(res)) + // let mut buffer = Vec::new(); + // for u in repr { + // buffer.extend(u.to_le_bytes()); + // } + // let big_int = F::BigInt::read(buffer.as_slice()) + // .map_err(|_| CurveDecodingError::NotInField(format!("{:?}", repr)))?; + // let res = + // F::from_repr(big_int).ok_or(CurveDecodingError::NotInField(format!("{:?}" + // , repr)))?; Ok(ArkField(res)) + todo!() } } #[derive(PartialEq, Eq, Copy, Clone, fmt::Debug)] pub struct ArkGroup< - G: ark_ec::ProjectiveCurve + Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display, + G: ark_ec::CurveGroup + Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display, >(G); impl< - G: ark_ec::ProjectiveCurve - + Sized - + Eq - + Copy - + Clone - + Send - + Sync - + fmt::Debug - + fmt::Display, + G: ark_ec::CurveGroup + Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display, > Serial for ArkGroup { fn serial(&self, _out: &mut B) { todo!() } } impl< - G: ark_ec::ProjectiveCurve - + Sized - + Eq - + Copy - + Clone - + Send - + Sync - + fmt::Debug - + fmt::Display, + G: ark_ec::CurveGroup + Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display, > Deserial for ArkGroup { fn deserial(_source: &mut R) -> crate::common::ParseResult { @@ -126,27 +100,21 @@ impl< } impl< - G: ark_ec::ProjectiveCurve - + Sized - + Eq - + Copy - + Clone - + Send - + Sync - + fmt::Debug - + fmt::Display, + G: ark_ec::CurveGroup + Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display, > From for ArkGroup { fn from(value: G) -> Self { ArkGroup(value) } } -pub(crate) trait CurveElementLength { +pub(crate) trait ArkCurveConfig { const SCALAR_LENGTH: usize; - const GROUP_ELEMENT_LENGTH: usize; + const DOMAIN_STRING: String; } -impl Curve for ArkGroup { +impl + ArkCurveConfig> Curve + for ArkGroup +{ type MultiExpType = GenericMultiExp; type Scalar = ArkField; @@ -155,7 +123,7 @@ impl Curve for ArkGroup { fn zero_point() -> Self { ArkGroup(G::zero()) } - fn one_point() -> Self { ArkGroup(G::prime_subgroup_generator()) } + fn one_point() -> Self { ArkGroup(G::generator()) } fn is_zero_point(&self) -> bool { self.0.is_zero() } @@ -168,25 +136,37 @@ impl Curve for ArkGroup { fn minus_point(&self, other: &Self) -> Self { ArkGroup(self.0 - other.0) } fn mul_by_scalar(&self, scalar: &Self::Scalar) -> Self { - ArkGroup(self.0.into_affine().mul(scalar.0)) + // ArkGroup(self.0.into_affine().mul(scalar.0)) + ArkGroup(self.0 * scalar.0) } fn bytes_to_curve_unchecked(_b: &mut R) -> anyhow::Result { todo!() } - fn generate(rng: &mut R) -> Self { ArkGroup(G::rand(rng)) } + fn generate(rng: &mut R) -> Self { + todo!() + // ArkGroup(G::rand(rng)) + } fn generate_scalar(rng: &mut R) -> Self::Scalar { - ArkField(::rand(rng)) + // ArkField(::rand(rng)) + todo!() } fn scalar_from_u64(n: u64) -> Self::Scalar { ArkField(G::ScalarField::from(n)) } fn scalar_from_bytes>(bs: A) -> Self::Scalar { - let res = G::ScalarField::read(bs.as_ref()).unwrap(); + let res = ::from_random_bytes(bs.as_ref()) + .expect("Input bytes must be a valid scalar values"); ArkField(res) } - fn hash_to_group(_m: &[u8]) -> Self { todo!() } + fn hash_to_group(m: &[u8]) -> Self { + let hasher = + G::new(G::DOMAIN_STRING.as_ref()).expect("Expected valid domain separation string"); + let res = >::hash(&hasher, &m) + .expect("Expected successful hashing to curve"); + ArkGroup(res.into()) + } } diff --git a/rust-src/concordium_base/src/curve_arithmetic/ed25519_ng_instance.rs b/rust-src/concordium_base/src/curve_arithmetic/ed25519_ng_instance.rs index 0f3abf2d4..d64c055ea 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/ed25519_ng_instance.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/ed25519_ng_instance.rs @@ -244,9 +244,6 @@ impl MultiExp for RistrettoMultiExpNoPrecompute { &self, exps: &[X], ) -> Self::CurvePoint { - Self::CurvePoint::vartime_multiscalar_mul( - exps.iter().map(|p| p.borrow().0), - &self.points, - ) + Self::CurvePoint::vartime_multiscalar_mul(exps.iter().map(|p| p.borrow().0), &self.points) } } From 01bacb69f59b7361e1344c2d0fb5467f05923b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Bizjak?= Date: Mon, 4 Dec 2023 10:31:30 +0100 Subject: [PATCH 02/53] Upgrade dalek to V2. --- identity-provider-service/Cargo.lock | 132 ++++++++++--- identity-provider-service/Cargo.toml | 2 +- idiss/Cargo.lock | 132 ++++++++++--- idiss/Cargo.toml | 2 +- mobile_wallet/Cargo.lock | 177 +++++++++++------- mobile_wallet/Cargo.toml | 2 +- rust-bins/Cargo.lock | 124 +++++++++--- rust-bins/Cargo.toml | 2 +- rust-bins/src/bin/client.rs | 2 +- rust-bins/src/bin/user_cli.rs | 2 +- rust-src/Cargo.lock | 121 +++++++++--- rust-src/concordium_base/Cargo.toml | 5 +- rust-src/concordium_base/src/base.rs | 99 +++++++--- rust-src/concordium_base/src/common/impls.rs | 27 +-- .../concordium_base/src/common/serialize.rs | 33 ++++ rust-src/concordium_base/src/common/types.rs | 101 ++++++---- .../src/eddsa_ed25519/dlog_ed25519.rs | 4 +- rust-src/concordium_base/src/id/id_prover.rs | 6 +- .../src/id/identity_provider.rs | 7 +- rust-src/concordium_base/src/id/types.rs | 35 ++-- rust-src/concordium_base/src/lib.rs | 2 +- rust-src/concordium_base/src/transactions.rs | 10 +- rust-src/concordium_base/src/web3id/did.rs | 4 +- rust-src/concordium_base/src/web3id/mod.rs | 50 ++--- rust-src/ed25519_hd_key_derivation/Cargo.toml | 2 +- rust-src/key_derivation/Cargo.toml | 2 +- 26 files changed, 742 insertions(+), 343 deletions(-) diff --git a/identity-provider-service/Cargo.lock b/identity-provider-service/Cargo.lock index 578f8b13a..096d1c718 100644 --- a/identity-provider-service/Cargo.lock +++ b/identity-provider-service/Cargo.lock @@ -144,6 +144,12 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bitflags" version = "1.3.2" @@ -364,7 +370,7 @@ dependencies = [ "chrono", "concordium-contracts-common", "concordium_base_derive", - "curve25519-dalek", + "curve25519-dalek 3.2.0", "derive_more", "ed25519-dalek", "either", @@ -379,8 +385,7 @@ dependencies = [ "num-bigint 0.4.4", "num-traits", "pairing", - "rand 0.7.3", - "rand_core 0.5.1", + "rand 0.8.5", "rayon", "rust_decimal", "serde", @@ -402,6 +407,12 @@ dependencies = [ "syn 2.0.37", ] +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + [[package]] name = "convert_case" version = "0.4.0" @@ -478,9 +489,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", "digest 0.9.0", @@ -489,6 +500,34 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "darling" version = "0.20.3" @@ -530,6 +569,16 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.8" @@ -573,24 +622,26 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.5.3" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ + "pkcs8", "signature", ] [[package]] name = "ed25519-dalek" -version = "1.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ - "curve25519-dalek", + "curve25519-dalek 4.1.1", "ed25519", - "rand 0.7.3", + "rand_core 0.6.4", "serde", - "sha2 0.9.9", + "sha2 0.10.8", + "subtle", "zeroize", ] @@ -680,6 +731,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "fiat-crypto" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" + [[package]] name = "fnv" version = "1.0.7" @@ -1500,12 +1557,28 @@ 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 = "pkg-config" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "platforms" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2087,9 +2160,12 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] [[package]] name = "simdutf8" @@ -2138,6 +2214,16 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "strsim" version = "0.8.0" @@ -2807,20 +2893,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/identity-provider-service/Cargo.toml b/identity-provider-service/Cargo.toml index 7af7483eb..ece0c7636 100644 --- a/identity-provider-service/Cargo.toml +++ b/identity-provider-service/Cargo.toml @@ -26,7 +26,7 @@ clap = "2.33" anyhow = "1.0" hex = "0.4" rust-embed = "6" -ed25519-dalek = "=1.0" +ed25519-dalek = "2.0" chrono = "0.4.24" # the patch version is necessary since chrono adds new functionality in patch versions sha2 = "0.10" diff --git a/idiss/Cargo.lock b/idiss/Cargo.lock index 756ac175e..5c1ed0667 100644 --- a/idiss/Cargo.lock +++ b/idiss/Cargo.lock @@ -92,6 +92,12 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bindgen" version = "0.56.0" @@ -349,7 +355,7 @@ dependencies = [ "chrono", "concordium-contracts-common", "concordium_base_derive", - "curve25519-dalek", + "curve25519-dalek 3.2.0", "derive_more", "ed25519-dalek", "either", @@ -364,8 +370,7 @@ dependencies = [ "num-bigint 0.4.4", "num-traits", "pairing", - "rand 0.7.3", - "rand_core 0.5.1", + "rand 0.8.5", "rayon", "rust_decimal", "serde", @@ -387,6 +392,12 @@ dependencies = [ "syn 2.0.37", ] +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + [[package]] name = "convert_case" version = "0.4.0" @@ -453,9 +464,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", "digest 0.9.0", @@ -464,6 +475,34 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "darling" version = "0.20.3" @@ -499,6 +538,16 @@ dependencies = [ "syn 2.0.37", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.8" @@ -542,24 +591,26 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.5.3" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ + "pkcs8", "signature", ] [[package]] name = "ed25519-dalek" -version = "1.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ - "curve25519-dalek", + "curve25519-dalek 4.1.1", "ed25519", - "rand 0.7.3", + "rand_core 0.6.4", "serde", - "sha2 0.9.9", + "sha2 0.10.8", + "subtle", "zeroize", ] @@ -613,6 +664,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "fiat-crypto" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" + [[package]] name = "fnv" version = "1.0.7" @@ -1040,6 +1097,22 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "platforms" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1422,9 +1495,12 @@ checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" [[package]] name = "signature" -version = "1.6.4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] [[package]] name = "simdutf8" @@ -1432,6 +1508,16 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "strsim" version = "0.8.0" @@ -1787,20 +1873,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/idiss/Cargo.toml b/idiss/Cargo.toml index 185e8fabb..0cd9b0845 100644 --- a/idiss/Cargo.toml +++ b/idiss/Cargo.toml @@ -32,7 +32,7 @@ hex = "0.4" serde = "1.0" serde_json = "1.0" chrono = "0.4.24" # the patch version is necessary since chrono adds new functionality in patch versions -ed25519-dalek = "1.0.1" +ed25519-dalek = "2.0" byteorder = "1.3" [dependencies.nodejs-sys] diff --git a/mobile_wallet/Cargo.lock b/mobile_wallet/Cargo.lock index 7ad789403..63bb1e84d 100644 --- a/mobile_wallet/Cargo.lock +++ b/mobile_wallet/Cargo.lock @@ -273,7 +273,7 @@ version = "4.0.1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -286,7 +286,7 @@ dependencies = [ "chrono", "concordium-contracts-common", "concordium_base_derive", - "curve25519-dalek", + "curve25519-dalek 3.2.0", "derive_more", "ed25519-dalek", "either", @@ -301,8 +301,7 @@ dependencies = [ "num-bigint 0.4.3", "num-traits", "pairing", - "rand 0.7.3", - "rand_core 0.5.1", + "rand 0.8.5", "rayon", "rust_decimal", "serde", @@ -321,9 +320,15 @@ version = "1.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + [[package]] name = "convert_case" version = "0.4.0" @@ -338,9 +343,9 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -400,9 +405,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", "digest 0.9.0", @@ -411,6 +416,34 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.6", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "cxx" version = "1.0.91" @@ -476,7 +509,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -487,7 +520,17 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn 2.0.18", + "syn 2.0.39", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", ] [[package]] @@ -525,24 +568,26 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.5.3" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ + "pkcs8", "signature", ] [[package]] name = "ed25519-dalek" -version = "1.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d2e93f837d749c16d118e7ddf7a4dfd0ac8f452cf51e46e9348824e5ef6851" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ - "curve25519-dalek", + "curve25519-dalek 4.1.1", "ed25519", - "rand 0.7.3", + "rand_core 0.6.4", "serde", - "sha2 0.9.9", + "sha2 0.10.6", + "subtle", "zeroize", ] @@ -598,6 +643,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "fiat-crypto" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" + [[package]] name = "fnv" version = "1.0.7" @@ -832,9 +883,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "link-cplusplus" @@ -1054,6 +1105,22 @@ dependencies = [ "sha2 0.10.6", ] +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "platforms" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1071,9 +1138,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -1100,9 +1167,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1343,7 +1410,7 @@ checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -1382,7 +1449,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -1421,9 +1488,12 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] [[package]] name = "simdutf8" @@ -1431,6 +1501,16 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "strsim" version = "0.10.0" @@ -1456,27 +1536,15 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - [[package]] name = "termcolor" version = "1.2.0" @@ -1571,12 +1639,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - [[package]] name = "unreachable" version = "1.0.0" @@ -1714,21 +1776,6 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "zeroize" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.3.3" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure", -] +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/mobile_wallet/Cargo.toml b/mobile_wallet/Cargo.toml index a1565832f..72c10eb46 100644 --- a/mobile_wallet/Cargo.toml +++ b/mobile_wallet/Cargo.toml @@ -16,7 +16,7 @@ serde = "1.0" serde_json = "1.0" anyhow = "1.0" chrono = "0.4.24" # the patch version is necessary since chrono adds new functionality in patch versions -ed25519-dalek = "=1.0.0" +ed25519-dalek = "2.0" byteorder = "1.3" either = "1.6" sha2 = "0.10" diff --git a/rust-bins/Cargo.lock b/rust-bins/Cargo.lock index d2efbf8d1..ca0a26980 100644 --- a/rust-bins/Cargo.lock +++ b/rust-bins/Cargo.lock @@ -390,7 +390,7 @@ dependencies = [ "chrono", "concordium-contracts-common", "concordium_base_derive", - "curve25519-dalek", + "curve25519-dalek 3.2.0", "derive_more", "ed25519-dalek", "either", @@ -407,8 +407,7 @@ dependencies = [ "num-traits", "pairing", "pbkdf2 0.11.0", - "rand 0.7.3", - "rand_core 0.5.1", + "rand 0.8.5", "rayon", "rust_decimal", "serde", @@ -443,6 +442,12 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + [[package]] name = "convert_case" version = "0.4.0" @@ -544,9 +549,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", "digest 0.9.0", @@ -555,6 +560,34 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "darling" version = "0.20.3" @@ -590,6 +623,16 @@ dependencies = [ "syn 2.0.37", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.8" @@ -646,24 +689,25 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.5.3" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" dependencies = [ + "pkcs8", "signature", ] [[package]] name = "ed25519-dalek" -version = "1.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek", + "curve25519-dalek 4.1.1", "ed25519", - "rand 0.7.3", + "rand_core 0.6.4", "serde", - "sha2 0.9.9", + "sha2 0.10.8", "zeroize", ] @@ -758,6 +802,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "fiat-crypto" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" + [[package]] name = "fnv" version = "1.0.7" @@ -1325,7 +1375,7 @@ dependencies = [ "clap", "concordium_base", "crossterm", - "curve25519-dalek", + "curve25519-dalek 3.2.0", "dialoguer", "ed25519-dalek", "ed25519_hd_key_derivation", @@ -1659,12 +1709,28 @@ 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 = "pkg-config" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "platforms" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2225,9 +2291,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" [[package]] name = "simdutf8" @@ -2270,6 +2336,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "strsim" version = "0.8.0" @@ -2861,20 +2937,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/rust-bins/Cargo.toml b/rust-bins/Cargo.toml index b92a9f9df..4b1149f68 100644 --- a/rust-bins/Cargo.toml +++ b/rust-bins/Cargo.toml @@ -17,7 +17,7 @@ pairing = "0.15" rand = "=0.7" serde = "1.0" serde_json = "1.0" -ed25519-dalek = "=1.0" +ed25519-dalek = "2.0" curve25519-dalek = "3.0" structopt = "0.3" hex = "0.4" diff --git a/rust-bins/src/bin/client.rs b/rust-bins/src/bin/client.rs index 39ec62bfd..4d7383d6f 100644 --- a/rust-bins/src/bin/client.rs +++ b/rust-bins/src/bin/client.rs @@ -1144,7 +1144,7 @@ fn handle_create_credential(cc: CreateCredential) { }; let cred_data = { let mut keys = std::collections::BTreeMap::new(); - let public = ed25519::PublicKey::from(&secret); + let public = ed25519::VerifyingKey::from(&secret); keys.insert(KeyIndex(0), KeyPair { secret, public }); CredentialData { diff --git a/rust-bins/src/bin/user_cli.rs b/rust-bins/src/bin/user_cli.rs index 52e82862f..4d38e4055 100644 --- a/rust-bins/src/bin/user_cli.rs +++ b/rust-bins/src/bin/user_cli.rs @@ -786,7 +786,7 @@ fn handle_create_credential_v1(cc: CreateCredentialV1) -> anyhow::Result<()> { }; let acc_data = { let mut keys = std::collections::BTreeMap::new(); - let public = ed25519::PublicKey::from(&secret); + let public = ed25519::VerifyingKey::from(&secret); keys.insert(KeyIndex(0), KeyPair { secret, public }); CredentialData { diff --git a/rust-src/Cargo.lock b/rust-src/Cargo.lock index dbef9c08d..92dcf108b 100644 --- a/rust-src/Cargo.lock +++ b/rust-src/Cargo.lock @@ -391,7 +391,7 @@ dependencies = [ "concordium-contracts-common", "concordium_base_derive", "criterion", - "curve25519-dalek", + "curve25519-dalek 3.2.0", "derive_more", "ed25519-dalek", "either", @@ -409,7 +409,7 @@ dependencies = [ "pairing", "pbkdf2 0.11.0", "rand 0.7.3", - "rand_core 0.5.1", + "rand 0.8.5", "rayon", "rust_decimal", "serde", @@ -431,6 +431,12 @@ dependencies = [ "syn 2.0.32", ] +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + [[package]] name = "convert_case" version = "0.4.0" @@ -543,9 +549,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", "digest 0.9.0", @@ -554,6 +560,34 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + [[package]] name = "darling" version = "0.20.3" @@ -589,6 +623,16 @@ dependencies = [ "syn 2.0.32", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.8" @@ -633,24 +677,25 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.5.3" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" dependencies = [ + "pkcs8", "signature", ] [[package]] name = "ed25519-dalek" -version = "1.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek", + "curve25519-dalek 4.1.1", "ed25519", - "rand 0.7.3", + "rand_core 0.6.4", "serde", - "sha2 0.9.9", + "sha2 0.10.7", "zeroize", ] @@ -703,6 +748,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "fiat-crypto" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" + [[package]] name = "fnv" version = "1.0.7" @@ -1188,6 +1239,22 @@ dependencies = [ "sha2 0.10.7", ] +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "platforms" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" + [[package]] name = "plotters" version = "0.3.5" @@ -1614,9 +1681,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" [[package]] name = "simdutf8" @@ -1624,6 +1691,16 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "strsim" version = "0.10.0" @@ -1970,20 +2047,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", -] +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/rust-src/concordium_base/Cargo.toml b/rust-src/concordium_base/Cargo.toml index 56b02c281..6bd0eb163 100644 --- a/rust-src/concordium_base/Cargo.toml +++ b/rust-src/concordium_base/Cargo.toml @@ -16,13 +16,12 @@ ff = "0.5" sha2 = "0.10" sha3 = "0.10" anyhow = "1.0" -rand_core = "=0.5" serde = {version = "1.0", features = ["derive"]} serde_json = "1.0" libc = "0.2" chrono = {version = "0.4.24", features = ["serde"]} # the patch version is necessary since chrono adds new functionality in patch versions serde_with = "3" -ed25519-dalek = "=1.0" +ed25519-dalek = {version = "2.0", features = ["rand_core"]} byteorder = "1.3" hex = "0.4" itertools = "0.10" @@ -30,7 +29,7 @@ either = "1.6" pairing = "0.15" derive_more = "0.99" thiserror = "1.0" -rand = "0.7" +rand = "0.8" num = "0.4" group = "0.2" curve25519-dalek = "3" diff --git a/rust-src/concordium_base/src/base.rs b/rust-src/concordium_base/src/base.rs index f6b08e2b7..8e5344177 100644 --- a/rust-src/concordium_base/src/base.rs +++ b/rust-src/concordium_base/src/base.rs @@ -21,6 +21,7 @@ pub use concordium_contracts_common::{ ZeroSignatureThreshold, }; use derive_more::{Add, Display, From, FromStr, Into, Sub}; +use ed25519_dalek::Signer; use rand::{CryptoRng, Rng}; use std::{ convert::{TryFrom, TryInto}, @@ -605,7 +606,7 @@ impl BakerSignatureSignKey { /// Generate a fresh key using the provided random number generator. pub fn generate(csprng: &mut T) -> Self { Self { - sign_key: ed25519_dalek::SecretKey::generate(csprng), + sign_key: csprng.gen(), } } } @@ -614,13 +615,13 @@ impl BakerSignatureSignKey { #[derive(SerdeBase16Serialize, Serialize, Clone, Debug, PartialEq, Eq)] /// A public key that corresponds to [`BakerSignatureVerifyKey`]. pub struct BakerSignatureVerifyKey { - pub(crate) verify_key: ed25519_dalek::PublicKey, + pub(crate) verify_key: ed25519_dalek::VerifyingKey, } impl From<&BakerSignatureSignKey> for BakerSignatureVerifyKey { fn from(secret: &BakerSignatureSignKey) -> Self { Self { - verify_key: ed25519_dalek::PublicKey::from(&secret.sign_key), + verify_key: ed25519_dalek::SigningKey::from(&secret.sign_key).verifying_key(), } } } @@ -777,46 +778,82 @@ pub struct UpdatePublicKey { /// A ed25519 keypair. This is available in the `ed25519::dalek` crate, but the /// JSON serialization there is not compatible with what we use, so we redefine /// it there. -#[derive(Debug, SerdeSerialize, SerdeDeserialize)] +#[derive(Debug, SerdeSerialize, SerdeDeserialize, derive_more::AsRef, Clone)] +#[serde( + try_from = "update_key_pair_json::UpdateKeyPair", + into = "update_key_pair_json::UpdateKeyPair" +)] pub struct UpdateKeyPair { - #[serde( - rename = "signKey", - serialize_with = "crate::common::base16_encode", - deserialize_with = "crate::common::base16_decode" - )] - pub secret: ed25519_dalek::SecretKey, - #[serde(flatten)] - pub public: UpdatePublicKey, + inner: ed25519_dalek::SigningKey, } -impl UpdateKeyPair { - /// Generate a fresh key pair using the provided random number generator. - pub fn generate(rng: &mut R) -> Self { - let kp = ed25519_dalek::Keypair::generate(rng); - Self { - secret: kp.secret, - public: UpdatePublicKey { - public: VerifyKey::Ed25519VerifyKey(kp.public), - }, +mod update_key_pair_json { + use crate::id::types::SchemeId; + + use super::*; + /// A ed25519 keypair. This is available in the `ed25519::dalek` crate, but + /// the JSON serialization there is not compatible with what we use, so + /// we redefine it there. + #[derive(Debug, SerdeSerialize, SerdeDeserialize)] + pub struct UpdateKeyPair { + #[serde( + rename = "signKey", + serialize_with = "crate::common::base16_encode_array", + deserialize_with = "crate::common::base16_decode_array" + )] + pub secret: ed25519_dalek::SecretKey, + #[serde( + rename = "verifyKey", + serialize_with = "crate::common::base16_encode", + deserialize_with = "crate::common::base16_decode" + )] + pub public: ed25519_dalek::VerifyingKey, + pub schema: Option, + } + + impl TryFrom for super::UpdateKeyPair { + type Error = ed25519_dalek::SignatureError; + + fn try_from(value: UpdateKeyPair) -> Result { + let inner = ed25519_dalek::SigningKey::from_bytes(&value.secret); + if inner.verifying_key() != value.public { + Err(ed25519_dalek::SignatureError::from_source( + "Public key does not match secret key.", + )) + } else { + Ok(Self { inner }) + } } } - /// Sign the message with the keypair. - pub fn sign(&self, msg: &[u8]) -> Signature { - let expanded = ed25519_dalek::ExpandedSecretKey::from(&self.secret); - match self.public.public { - VerifyKey::Ed25519VerifyKey(vf) => { - let sig = expanded.sign(msg, &vf); - Signature { - sig: sig.to_bytes().to_vec(), - } + impl From for UpdateKeyPair { + fn from(value: super::UpdateKeyPair) -> Self { + Self { + secret: value.inner.to_bytes(), + public: value.inner.verifying_key(), + schema: Some(SchemeId::Ed25519), } } } } +impl UpdateKeyPair { + /// Generate a fresh key pair using the provided random number generator. + pub fn generate(rng: &mut R) -> Self { + let inner = ed25519_dalek::SigningKey::generate(rng); + Self { inner } + } + + /// Sign the message with the keypair. + pub fn sign(&self, msg: &[u8]) -> Signature { self.inner.sign(msg).into() } +} + impl From<&UpdateKeyPair> for UpdatePublicKey { - fn from(kp: &UpdateKeyPair) -> Self { kp.public.clone() } + fn from(kp: &UpdateKeyPair) -> Self { + UpdatePublicKey { + public: kp.inner.verifying_key().into(), + } + } } #[derive(Debug, Clone, Copy, SerdeSerialize, SerdeDeserialize, Serialize, Into, Display)] diff --git a/rust-src/concordium_base/src/common/impls.rs b/rust-src/concordium_base/src/common/impls.rs index 935c59e2a..238cbf8a3 100644 --- a/rust-src/concordium_base/src/common/impls.rs +++ b/rust-src/concordium_base/src/common/impls.rs @@ -158,45 +158,30 @@ impl Serial for Fq12 { use ed25519_dalek::*; -impl Deserial for PublicKey { +impl Deserial for VerifyingKey { fn deserial(source: &mut R) -> ParseResult { let mut buf = [0u8; PUBLIC_KEY_LENGTH]; source.read_exact(&mut buf)?; - Ok(PublicKey::from_bytes(&buf)?) + Ok(VerifyingKey::from_bytes(&buf)?) } } -impl Serial for PublicKey { +impl Serial for VerifyingKey { fn serial(&self, out: &mut B) { out.write_all(self.as_bytes()) .expect("Writing to buffer should succeed."); } } -impl Deserial for SecretKey { - fn deserial(source: &mut R) -> ParseResult { - let mut buf = [0u8; SECRET_KEY_LENGTH]; - source.read_exact(&mut buf)?; - Ok(SecretKey::from_bytes(&buf)?) - } -} - -impl Serial for SecretKey { - fn serial(&self, out: &mut B) { - out.write_all(self.as_bytes()) - .expect("Writing to buffer should succeed."); - } -} - -impl Deserial for Keypair { +impl Deserial for SigningKey { fn deserial(source: &mut R) -> ParseResult { let mut buf = [0u8; KEYPAIR_LENGTH]; source.read_exact(&mut buf)?; - Ok(Keypair::from_bytes(&buf)?) + Ok(SigningKey::from_keypair_bytes(&buf)?) } } -impl Serial for Keypair { +impl Serial for SigningKey { fn serial(&self, out: &mut B) { out.write_all(&self.to_bytes()) .expect("Writing to buffer should succeed."); diff --git a/rust-src/concordium_base/src/common/serialize.rs b/rust-src/concordium_base/src/common/serialize.rs index a64eca48c..6882b0f25 100644 --- a/rust-src/concordium_base/src/common/serialize.rs +++ b/rust-src/concordium_base/src/common/serialize.rs @@ -877,6 +877,39 @@ pub fn base16_decode<'de, D: Deserializer<'de>, T: Deserial>(des: D) -> Result( + v: &[u8; N], + ser: S, +) -> Result { + let b16_str = encode(v); + ser.serialize_str(&b16_str) +} + +/// Dual to [`base16_encode_array`]. More efficient than [`base16_decode`] since +/// it reads the entire byte array in one chunk. +pub(crate) fn base16_decode_array<'de, D: Deserializer<'de>, const N: usize>( + des: D, +) -> Result<[u8; N], D::Error> { + struct Base16Visitor(std::marker::PhantomData<[u8; N]>); + + impl<'de, const N: usize> Visitor<'de> for Base16Visitor { + type Value = [u8; N]; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "A base 16 string.") + } + + fn visit_str(self, v: &str) -> Result { + let bytes = decode(v).map_err(de::Error::custom)?; + bytes.try_into().map_err(|_|de::Error::custom("Unexpected array length.")) + } + } + + des.deserialize_str(Base16Visitor(Default::default())) +} + /// Analogous to [base16_encode], but encodes into a string rather than a serde /// Serializer. pub fn base16_encode_string(x: &S) -> String { encode(to_bytes(x)) } diff --git a/rust-src/concordium_base/src/common/types.rs b/rust-src/concordium_base/src/common/types.rs index f1465d991..1d592d8c8 100644 --- a/rust-src/concordium_base/src/common/types.rs +++ b/rust-src/concordium_base/src/common/types.rs @@ -12,6 +12,7 @@ use concordium_contracts_common::{ }; pub use concordium_contracts_common::{AccountAddress, Address, Amount, ACCOUNT_ADDRESS_SIZE}; use derive_more::{Display, From, FromStr, Into}; +use ed25519_dalek::Signer; use std::{collections::BTreeMap, num::ParseIntError, str::FromStr}; /// Index of an account key that is to be used. #[derive( @@ -308,6 +309,14 @@ pub struct Signature { pub sig: Vec, } +impl From for Signature { + fn from(value: ed25519_dalek::Signature) -> Self { + Self { + sig: value.to_vec(), + } + } +} + impl Serial for Signature { fn serial(&self, out: &mut B) { (self.sig.len() as u16).serial(out); @@ -472,58 +481,78 @@ impl FromStr for Timestamp { } } -/// A ed25519 keypair. This is available in the `ed25519::dalek` crate, but the +/// A ed25519 keypair. This is available in the `ed25519_dalek` crate, but the /// JSON serialization there is not compatible with what we use, so we redefine /// it there. -#[derive(Debug, SerdeSerialize, SerdeDeserialize)] +#[derive( + Debug, + SerdeSerialize, + SerdeDeserialize, + derive_more::AsRef, + derive_more::From, + derive_more::Into, + Clone, +)] +#[serde(try_from = "key_pair_json::KeyPair", into = "key_pair_json::KeyPair")] pub struct KeyPair { - #[serde( - rename = "signKey", - serialize_with = "crate::common::base16_encode", - deserialize_with = "crate::common::base16_decode" - )] - pub secret: ed25519_dalek::SecretKey, - #[serde( - rename = "verifyKey", - serialize_with = "crate::common::base16_encode", - deserialize_with = "crate::common::base16_decode" - )] - pub public: ed25519_dalek::PublicKey, + inner: ed25519_dalek::SigningKey, } impl KeyPair { - pub fn generate(rng: &mut R) -> Self { - Self::from(ed25519_dalek::Keypair::generate(rng)) + pub fn public(&self) -> ed25519_dalek::VerifyingKey { + self.inner.verifying_key() + } +} + +mod key_pair_json { + #[derive(Debug, super::SerdeSerialize, super::SerdeDeserialize)] + pub struct KeyPair { + #[serde( + rename = "signKey", + serialize_with = "crate::common::base16_encode_array", + deserialize_with = "crate::common::base16_decode_array" + )] + pub secret: ed25519_dalek::SecretKey, + #[serde( + rename = "verifyKey", + serialize_with = "crate::common::base16_encode", + deserialize_with = "crate::common::base16_decode" + )] + pub public: ed25519_dalek::VerifyingKey, + } + + impl TryFrom for super::KeyPair { + type Error = ed25519_dalek::SignatureError; + + fn try_from(value: KeyPair) -> Result { + let inner = ed25519_dalek::SigningKey::from_bytes(&value.secret); + if inner.verifying_key() != value.public { + Err(Self::Error::from_source("Public/secret key mismatch.")) + } else { + Ok(Self { inner }) + } + } } -} -impl From for KeyPair { - fn from(kp: ed25519_dalek::Keypair) -> Self { - Self { - secret: kp.secret, - public: kp.public, + impl From for KeyPair { + fn from(value: super::KeyPair) -> Self { + Self { + secret: value.inner.to_bytes(), + public: value.inner.verifying_key(), + } } } } impl KeyPair { - /// Sign the given message with the keypair. - pub fn sign(&self, msg: &[u8]) -> Signature { - let expanded = ed25519_dalek::ExpandedSecretKey::from(&self.secret); - let sig = expanded.sign(msg, &self.public); - Signature { - sig: sig.to_bytes().to_vec(), - } + pub fn generate(rng: &mut R) -> Self { + Self::from(ed25519_dalek::SigningKey::generate(rng)) } } -impl From for ed25519_dalek::Keypair { - fn from(kp: KeyPair) -> ed25519_dalek::Keypair { - ed25519_dalek::Keypair { - secret: kp.secret, - public: kp.public, - } - } +impl KeyPair { + /// Sign the given message with the keypair. + pub fn sign(&self, msg: &[u8]) -> ed25519_dalek::Signature { self.inner.sign(msg) } } #[cfg(test)] diff --git a/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs b/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs index 3e5753f6a..e81d6f1eb 100644 --- a/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs +++ b/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs @@ -72,7 +72,7 @@ fn scalar_from_secret_key(secret_key: &impl AsRef<[u8]>) -> Scalar { Scalar::from_bits(bits) } -fn point_from_public_key(public_key: &PublicKey) -> Option { +fn point_from_public_key(public_key: &VerifyingKey) -> Option { let bytes = public_key.to_bytes(); CompressedEdwardsY::from_slice(&bytes).decompress() } @@ -115,7 +115,7 @@ pub fn prove_dlog_ed25519( pub fn verify_dlog_ed25519( ro: &mut RandomOracle, - public_key: &PublicKey, + public_key: &VerifyingKey, proof: &Ed25519DlogProof, ) -> bool { match point_from_public_key(public_key) { diff --git a/rust-src/concordium_base/src/id/id_prover.rs b/rust-src/concordium_base/src/id/id_prover.rs index de7957b4a..98bd73ea4 100644 --- a/rust-src/concordium_base/src/id/id_prover.rs +++ b/rust-src/concordium_base/src/id/id_prover.rs @@ -17,7 +17,6 @@ use crate::{ dlog::{Dlog, DlogSecret}, }, }; -use ed25519_dalek as ed25519; use sha2::{Digest, Sha256}; /// Function for producing a proof of a statement. @@ -197,10 +196,7 @@ pub fn prove_ownership_of_account( let sigs = data .keys .iter() - .map(|(&idx, kp)| { - let expanded_sk = ed25519::ExpandedSecretKey::from(&kp.secret); - (idx, expanded_sk.sign(to_sign, &kp.public).into()) - }) + .map(|(&idx, kp)| (idx, kp.sign(to_sign).into())) .collect(); AccountOwnershipProof { sigs } } diff --git a/rust-src/concordium_base/src/id/identity_provider.rs b/rust-src/concordium_base/src/id/identity_provider.rs index fa63f74be..dc627515d 100644 --- a/rust-src/concordium_base/src/id/identity_provider.rs +++ b/rust-src/concordium_base/src/id/identity_provider.rs @@ -10,6 +10,7 @@ use crate::{ random_oracle::RandomOracle, sigma_protocols::{com_enc_eq, com_eq, com_eq_different_groups, common::*, dlog}, }; +use ed25519_dalek::Signer as _; use ff::Field; use rand::*; use sha2::{Digest, Sha256}; @@ -568,9 +569,9 @@ fn sign_initial_cred_values< hasher.update(&to_bytes(&expiry)); hasher.update(&to_bytes(&initial_cred_values)); let to_sign = hasher.finalize(); - let expanded_sk = ed25519_dalek::ExpandedSecretKey::from(ip_cdi_secret_key); - expanded_sk - .sign(to_sign.as_ref(), &ip_info.ip_cdi_verify_key) + let signing_key = ed25519_dalek::SigningKey::from(ip_cdi_secret_key); + signing_key + .sign(to_sign.as_ref()) .into() } diff --git a/rust-src/concordium_base/src/id/types.rs b/rust-src/concordium_base/src/id/types.rs index dd2169bc9..5a6ad4d09 100644 --- a/rust-src/concordium_base/src/id/types.rs +++ b/rust-src/concordium_base/src/id/types.rs @@ -1080,7 +1080,7 @@ pub struct IpInfo { serialize_with = "base16_encode", deserialize_with = "base16_decode" )] - pub ip_cdi_verify_key: ed25519::PublicKey, + pub ip_cdi_verify_key: ed25519::VerifyingKey, } /// Collection of identity providers. @@ -1371,9 +1371,10 @@ impl> Deserial for Policy SerdeDeserialize<'de> for VerifyKey { } } -impl From for VerifyKey { - fn from(pk: ed25519::PublicKey) -> Self { VerifyKey::Ed25519VerifyKey(pk) } +impl From for VerifyKey { + fn from(pk: ed25519::VerifyingKey) -> Self { VerifyKey::Ed25519VerifyKey(pk) } } -impl From<&ed25519::Keypair> for VerifyKey { - fn from(kp: &ed25519::Keypair) -> Self { VerifyKey::Ed25519VerifyKey(kp.public) } +impl From<&ed25519::SigningKey> for VerifyKey { + fn from(kp: &ed25519::SigningKey) -> Self { VerifyKey::Ed25519VerifyKey(kp.verifying_key()) } } impl From<&KeyPair> for VerifyKey { - fn from(kp: &KeyPair) -> Self { VerifyKey::Ed25519VerifyKey(kp.public) } + fn from(kp: &KeyPair) -> Self { VerifyKey::Ed25519VerifyKey(kp.public()) } } /// Compare byte representation. @@ -2065,7 +2066,7 @@ impl From for AccountPublicKeys { inner_map.insert( u8::from(key_index), concordium_contracts_common::PublicKey::Ed25519(PublicKeyEd25519( - *public_key.public.as_bytes(), + *public_key.public().as_bytes(), )), ); } @@ -2131,7 +2132,7 @@ impl AccountKeys { let cred_sigs = cred_keys .keys .iter() - .map(|(ki, kp)| (*ki, kp.sign(msg))) + .map(|(ki, kp)| (*ki, kp.sign(msg).into())) .collect::>(); signatures.insert(*ci, cred_sigs); } @@ -2154,7 +2155,7 @@ impl AccountKeys { concordium_contracts_common::Signature::Ed25519(SignatureEd25519( // Unwrap is safe since the conversion is between signature types // represented by byte arrays of the same length [u8, u64]. - kp.sign(msg).sig.try_into().unwrap(), + kp.sign(msg).to_bytes().try_into().unwrap(), )), ) }) @@ -2223,7 +2224,7 @@ impl PublicCredentialData for CredentialData { fn get_public_keys(&self) -> BTreeMap { self.keys .iter() - .map(|(&idx, kp)| (idx, VerifyKey::Ed25519VerifyKey(kp.public))) + .map(|(&idx, kp)| (idx, kp.into())) .collect() } } @@ -2242,8 +2243,7 @@ impl CredentialDataWithSigning for CredentialData { self.keys .iter() .map(|(&idx, kp)| { - let expanded_sk = ed25519::ExpandedSecretKey::from(&kp.secret); - (idx, expanded_sk.sign(&to_sign, &kp.public).into()) + (idx, kp.sign(&to_sign).into()) }) .collect() } @@ -2264,7 +2264,7 @@ impl PublicInitialAccountData for InitialAccountData { fn get_public_keys(&self) -> BTreeMap { self.keys .iter() - .map(|(&idx, kp)| (idx, VerifyKey::Ed25519VerifyKey(kp.public))) + .map(|(&idx, kp)| (idx, kp.into())) .collect() } } @@ -2278,8 +2278,7 @@ impl InitialAccountDataWithSigning for InitialAccountData { self.keys .iter() .map(|(&idx, kp)| { - let expanded_sk = ed25519::ExpandedSecretKey::from(&kp.secret); - (idx, expanded_sk.sign(&to_sign, &kp.public).into()) + (idx, kp.sign(&to_sign).into()) }) .collect() } diff --git a/rust-src/concordium_base/src/lib.rs b/rust-src/concordium_base/src/lib.rs index 9c6e180e5..064b02761 100644 --- a/rust-src/concordium_base/src/lib.rs +++ b/rust-src/concordium_base/src/lib.rs @@ -35,7 +35,7 @@ pub mod dodis_yampolskiy_prf; /// We expose the `PublicKey`, `SecretKey`, and `Signature` from the third-party /// `ed25519_dalek` crate here because these types appear in Concordium's API. pub mod ed25519 { - pub use ed25519_dalek::{PublicKey, SecretKey, Signature}; + pub use ed25519_dalek::{VerifyingKey as PublicKey, SecretKey, Signature}; } #[cfg(feature = "ffi")] diff --git a/rust-src/concordium_base/src/transactions.rs b/rust-src/concordium_base/src/transactions.rs index 24cd35c8b..32dfdc8f7 100644 --- a/rust-src/concordium_base/src/transactions.rs +++ b/rust-src/concordium_base/src/transactions.rs @@ -1391,7 +1391,7 @@ impl TransactionSigner for AccountKeys { for (ci, cred_keys) in iter { let cred_sigs = cred_keys .into_iter() - .map(|(ki, kp)| (*ki, kp.sign(hash_to_sign.as_ref()))) + .map(|(ki, kp)| (*ki, kp.sign(hash_to_sign.as_ref()).into())) .collect::>(); signatures.insert(*ci, cred_sigs); } @@ -1418,7 +1418,7 @@ impl TransactionSigner for BTreeMap for (ci, cred_keys) in self { let cred_sigs = cred_keys .iter() - .map(|(ki, kp)| (*ki, kp.sign(hash_to_sign.as_ref()))) + .map(|(ki, kp)| (*ki, kp.sign(hash_to_sign.as_ref()).into())) .collect::>(); signatures.insert(*ci, cred_sigs); } @@ -1470,7 +1470,7 @@ pub struct AccountAccessStructure { pub type AccountStructure<'a> = &'a [( CredentialIndex, SignatureThreshold, - &'a [(KeyIndex, ed25519_dalek::PublicKey)], + &'a [(KeyIndex, ed25519_dalek::VerifyingKey)], )]; impl AccountAccessStructure { @@ -1504,7 +1504,7 @@ impl AccountAccessStructure { /// Generate a new [`AccountAccessStructure`] with a single credential and /// public key, at credential and key indices 0. - pub fn singleton(public_key: ed25519_dalek::PublicKey) -> Self { + pub fn singleton(public_key: ed25519_dalek::VerifyingKey) -> Self { Self::new(AccountThreshold::ONE, &[( 0.into(), SignatureThreshold::ONE, @@ -1525,7 +1525,7 @@ impl From<&AccountKeys> for AccountAccessStructure { keys: v .keys .iter() - .map(|(ki, kp)| (*ki, VerifyKey::Ed25519VerifyKey(kp.public))) + .map(|(ki, kp)| (*ki, VerifyKey::Ed25519VerifyKey(kp.as_ref().verifying_key()))) .collect(), threshold: v.threshold, }) diff --git a/rust-src/concordium_base/src/web3id/did.rs b/rust-src/concordium_base/src/web3id/did.rs index 5841db7df..5a0707ed7 100644 --- a/rust-src/concordium_base/src/web3id/did.rs +++ b/rust-src/concordium_base/src/web3id/did.rs @@ -87,7 +87,7 @@ pub enum IdentifierType { parameter: OwnedParameter, }, /// Reference to a specific Ed25519 public key. - PublicKey { key: ed25519_dalek::PublicKey }, + PublicKey { key: ed25519_dalek::VerifyingKey }, /// Reference to a specific identity provider. Idp { idp_identity: IpIdentity }, } @@ -116,7 +116,7 @@ impl IdentifierType { /// If `self` is the [`PublicKey`](Self::PublicKey) variant then extract the /// public key, otherwise return [`None`]. - pub fn extract_public_key(&self) -> Option { + pub fn extract_public_key(&self) -> Option { let IdentifierType::PublicKey { key, } = self else { diff --git a/rust-src/concordium_base/src/web3id/mod.rs b/rust-src/concordium_base/src/web3id/mod.rs index 66b435293..75ce916ca 100644 --- a/rust-src/concordium_base/src/web3id/mod.rs +++ b/rust-src/concordium_base/src/web3id/mod.rs @@ -106,8 +106,8 @@ impl + DeserializeOwned> TryFrom> { /// An ed25519 public key tagged with a phantom type parameter based on its /// role, e.g., an owner of a credential or a revocation key. pub struct Ed25519PublicKey { - pub public_key: ed25519_dalek::PublicKey, + pub public_key: ed25519_dalek::VerifyingKey, phantom: PhantomData, } -impl From for Ed25519PublicKey { - fn from(value: ed25519_dalek::PublicKey) -> Self { Self::new(value) } +impl From for Ed25519PublicKey { + fn from(value: ed25519_dalek::VerifyingKey) -> Self { Self::new(value) } } impl serde::Serialize for Ed25519PublicKey { @@ -682,13 +682,17 @@ impl TryFrom<&str> for Ed25519PublicKey { type Error = Ed25519PublicKeyFromStrError; fn try_from(value: &str) -> Result { - let bytes = hex::decode(value)?; - Ok(Self::new(ed25519_dalek::PublicKey::from_bytes(&bytes)?)) + let bytes: [u8; 32] = hex::decode(value)?.try_into().map_err(|e| { + Self::Error::InvalidBytes(ed25519_dalek::SignatureError::from_source( + "Incorrect public key length.", + )) + })?; + Ok(Self::new(ed25519_dalek::VerifyingKey::from_bytes(&bytes)?)) } } impl Ed25519PublicKey { - pub fn new(public_key: ed25519_dalek::PublicKey) -> Self { + pub fn new(public_key: ed25519_dalek::VerifyingKey) -> Self { Self { public_key, phantom: PhantomData, @@ -743,7 +747,7 @@ impl crate::contracts_common::Deserial for Ed25519PublicKey { source: &mut R, ) -> crate::contracts_common::ParseResult { let public_key_bytes = <[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>::deserial(source)?; - let public_key = ed25519_dalek::PublicKey::from_bytes(&public_key_bytes) + let public_key = ed25519_dalek::VerifyingKey::from_bytes(&public_key_bytes) .map_err(|_| crate::contracts_common::ParseError {})?; Ok(Self { public_key, @@ -763,7 +767,7 @@ impl crate::common::Deserial for Ed25519PublicKey { fn deserial(source: &mut R) -> crate::common::ParseResult { use anyhow::Context; let public_key_bytes = <[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>::deserial(source)?; - let public_key = ed25519_dalek::PublicKey::from_bytes(&public_key_bytes) + let public_key = ed25519_dalek::VerifyingKey::from_bytes(&public_key_bytes) .context("Invalid public key.")?; Ok(Self { public_key, @@ -991,12 +995,12 @@ impl TryFrom for LinkingProof { /// credential. The intention is that this is implemented by ed25519 keypairs /// or hardware wallets. pub trait Web3IdSigner { - fn id(&self) -> ed25519_dalek::PublicKey; + fn id(&self) -> ed25519_dalek::VerifyingKey; fn sign(&self, msg: &impl AsRef<[u8]>) -> ed25519_dalek::Signature; } -impl Web3IdSigner for ed25519_dalek::Keypair { - fn id(&self) -> ed25519_dalek::PublicKey { self.public } +impl Web3IdSigner for ed25519_dalek::SigningKey { + fn id(&self) -> ed25519_dalek::VerifyingKey { self.verifying_key() } fn sign(&self, msg: &impl AsRef<[u8]>) -> ed25519_dalek::Signature { ed25519_dalek::Signer::sign(self, msg.as_ref()) @@ -1004,17 +1008,17 @@ impl Web3IdSigner for ed25519_dalek::Keypair { } impl Web3IdSigner for crate::common::types::KeyPair { - fn id(&self) -> ed25519_dalek::PublicKey { self.public } + fn id(&self) -> ed25519_dalek::VerifyingKey { self.public() } - fn sign(&self, msg: &impl AsRef<[u8]>) -> ed25519_dalek::Signature { self.secret.sign(msg) } + fn sign(&self, msg: &impl AsRef<[u8]>) -> ed25519_dalek::Signature { self.sign(msg.as_ref()) } } impl Web3IdSigner for ed25519_dalek::SecretKey { - fn id(&self) -> ed25519_dalek::PublicKey { self.into() } + fn id(&self) -> ed25519_dalek::VerifyingKey { ed25519_dalek::SigningKey::from(self).verifying_key() } fn sign(&self, msg: &impl AsRef<[u8]>) -> ed25519_dalek::Signature { - let expanded: ed25519_dalek::ExpandedSecretKey = self.into(); - expanded.sign(msg.as_ref(), &self.into()) + let expanded: ed25519_dalek::SigningKey = self.into(); + ed25519_dalek::Signer::sign(&expanded, msg.as_ref()) } } @@ -1161,7 +1165,7 @@ impl TryFrom }; anyhow::ensure!(entrypoint == "credentialEntry", "Incorrect entrypoint."); let holder_id = - CredentialHolderId::new(ed25519_dalek::PublicKey::from_bytes(parameter.as_ref())?); + CredentialHolderId::new(ed25519_dalek::VerifyingKey::from_bytes(parameter.as_ref().try_into()?)?); // Just validate the issuer field. { @@ -1789,10 +1793,10 @@ mod tests { fn test_web3_only() -> anyhow::Result<()> { let mut rng = rand::thread_rng(); let challenge = Challenge::new(rng.gen()); - let signer_1 = ed25519_dalek::Keypair::generate(&mut rng); - let signer_2 = ed25519_dalek::Keypair::generate(&mut rng); - let issuer_1 = ed25519_dalek::Keypair::generate(&mut rng); - let issuer_2 = ed25519_dalek::Keypair::generate(&mut rng); + let signer_1 = ed25519_dalek::SigningKey::generate(&mut rng); + let signer_2 = ed25519_dalek::SigningKey::generate(&mut rng); + let issuer_1 = ed25519_dalek::SigningKey::generate(&mut rng); + let issuer_2 = ed25519_dalek::SigningKey::generate(&mut rng); let contract_1 = ContractAddress::new(1337, 42); let contract_2 = ContractAddress::new(1338, 0); let credential_statements = vec![ diff --git a/rust-src/ed25519_hd_key_derivation/Cargo.toml b/rust-src/ed25519_hd_key_derivation/Cargo.toml index 973f20717..fb8664732 100644 --- a/rust-src/ed25519_hd_key_derivation/Cargo.toml +++ b/rust-src/ed25519_hd_key_derivation/Cargo.toml @@ -10,7 +10,7 @@ hex = "0.4.3" hmac = "0.12.1" sha2 = "0.10.2" regex = "1.5.5" -ed25519-dalek = "=1.0" +ed25519-dalek = "2.0" thiserror = "1.0" [lib] diff --git a/rust-src/key_derivation/Cargo.toml b/rust-src/key_derivation/Cargo.toml index 5243e0feb..5882ce206 100644 --- a/rust-src/key_derivation/Cargo.toml +++ b/rust-src/key_derivation/Cargo.toml @@ -8,7 +8,7 @@ license-file = "../../LICENSE" [dependencies] hmac = "0.12.1" sha2 = "0.10.2" -ed25519-dalek = "1.0.0" +ed25519-dalek = "2.0" serde = "1" pbkdf2 = "0.10" From 6e5a6531c5dcb65bb7a45a02a7578345dfdaaf24 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Tue, 5 Dec 2023 13:21:03 +0100 Subject: [PATCH 03/53] Done with ArkWorks integration --- identity-provider-service/Cargo.lock | 149 +++++++------- idiss/Cargo.lock | 149 +++++++------- mobile_wallet/Cargo.lock | 182 +++++++++++------- rust-bins/Cargo.lock | 149 +++++++------- rust-src/Cargo.lock | 57 +++--- rust-src/concordium_base/Cargo.toml | 8 +- .../benches/range_proof_bench.rs | 2 +- .../src/bulletproofs/range_proof.rs | 9 +- .../curve_arithmetic/arkworks_instances.rs | 144 +++++++------- .../curve_arithmetic/bls12_381_arkworks.rs | 45 +++++ .../src/curve_arithmetic/ed25519_arkworks.rs | 2 +- .../src/curve_arithmetic/mod.rs | 1 + 12 files changed, 519 insertions(+), 378 deletions(-) create mode 100644 rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs diff --git a/identity-provider-service/Cargo.lock b/identity-provider-service/Cargo.lock index 59cd20194..170b95a90 100644 --- a/identity-provider-service/Cargo.lock +++ b/identity-provider-service/Cargo.lock @@ -48,6 +48,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -78,41 +84,54 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + [[package]] name = "ark-ec" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56006994f509d76fbce6f6ffe3108f7191b4f3754ecd00bbae7cac20ec05020" +version = "0.4.2" dependencies = [ "ark-ff", + "ark-poly", "ark-serialize", "ark-std", "derivative", + "hashbrown 0.14.1", + "itertools 0.12.0", + "num-bigint 0.4.4", "num-traits", "zeroize", ] [[package]] name = "ark-ff" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d8802d40fce9212c5c09be08f75c4b3becc0c488e87f60fff787b01250ce33" +version = "0.4.2" dependencies = [ "ark-ff-asm", "ark-ff-macros", "ark-serialize", "ark-std", + "arrayvec", "derivative", + "digest 0.10.7", + "itertools 0.12.0", + "num-bigint 0.4.4", "num-traits", - "rustc_version 0.3.3", + "paste", + "rustc_version", "zeroize", ] [[package]] name = "ark-ff-asm" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e8cb28c2137af1ef058aa59616db3f7df67dbb70bf2be4ee6920008cc30d98c" +version = "0.4.2" dependencies = [ "quote", "syn 1.0.109", @@ -120,33 +139,51 @@ dependencies = [ [[package]] name = "ark-ff-macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9c256a93a10ed9708c16a517d6dcfaba3d215c0d7fab44d29a9affefb5eeb8" +version = "0.4.2" dependencies = [ "num-bigint 0.4.4", "num-traits", + "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "ark-poly" +version = "0.4.2" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.14.1", +] + [[package]] name = "ark-serialize" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e9b59329dc9b92086b3dc619f31cef4a0c802f10829b575a3666d48a48387d" +version = "0.4.2" dependencies = [ + "ark-serialize-derive", "ark-std", + "digest 0.10.7", + "num-bigint 0.4.4", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "ark-std" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5b856a29bea7b810858116a596beee3d20fc4c5aeb240e8e5a8bca4845a470" +version = "0.4.0" dependencies = [ + "num-traits", "rand 0.7.3", - "rand_xorshift", ] [[package]] @@ -466,8 +503,11 @@ name = "concordium_base" version = "3.2.0" dependencies = [ "anyhow", + "ark-bls12-381", "ark-ec", "ark-ff", + "ark-serialize", + "ark-std", "bs58", "bulletproofs", "byteorder", @@ -482,7 +522,7 @@ dependencies = [ "ff", "group", "hex", - "itertools", + "itertools 0.10.5", "leb128", "libc", "merlin", @@ -685,7 +725,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.0", + "rustc_version", "syn 1.0.109", ] @@ -992,6 +1032,10 @@ name = "hashbrown" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +dependencies = [ + "ahash 0.8.3", + "allocator-api2", +] [[package]] name = "headers" @@ -1225,6 +1269,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -1612,21 +1665,16 @@ dependencies = [ ] [[package]] -name = "percent-encoding" -version = "2.3.0" +name = "paste" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] -name = "pest" -version = "2.7.5" +name = "percent-encoding" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project" @@ -2017,22 +2065,13 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.19", + "semver", ] [[package]] @@ -2122,30 +2161,12 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" version = "1.0.188" @@ -2664,12 +2685,6 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - [[package]] name = "unicase" version = "2.7.0" diff --git a/idiss/Cargo.lock b/idiss/Cargo.lock index f1ba047cc..70dcadcbc 100644 --- a/idiss/Cargo.lock +++ b/idiss/Cargo.lock @@ -33,6 +33,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -63,41 +69,54 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + [[package]] name = "ark-ec" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56006994f509d76fbce6f6ffe3108f7191b4f3754ecd00bbae7cac20ec05020" +version = "0.4.2" dependencies = [ "ark-ff", + "ark-poly", "ark-serialize", "ark-std", "derivative", + "hashbrown 0.14.1", + "itertools 0.12.0", + "num-bigint 0.4.4", "num-traits", "zeroize", ] [[package]] name = "ark-ff" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d8802d40fce9212c5c09be08f75c4b3becc0c488e87f60fff787b01250ce33" +version = "0.4.2" dependencies = [ "ark-ff-asm", "ark-ff-macros", "ark-serialize", "ark-std", + "arrayvec", "derivative", + "digest 0.10.7", + "itertools 0.12.0", + "num-bigint 0.4.4", "num-traits", - "rustc_version 0.3.3", + "paste", + "rustc_version", "zeroize", ] [[package]] name = "ark-ff-asm" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e8cb28c2137af1ef058aa59616db3f7df67dbb70bf2be4ee6920008cc30d98c" +version = "0.4.2" dependencies = [ "quote", "syn 1.0.109", @@ -105,33 +124,51 @@ dependencies = [ [[package]] name = "ark-ff-macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9c256a93a10ed9708c16a517d6dcfaba3d215c0d7fab44d29a9affefb5eeb8" +version = "0.4.2" dependencies = [ "num-bigint 0.4.4", "num-traits", + "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "ark-poly" +version = "0.4.2" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.14.1", +] + [[package]] name = "ark-serialize" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e9b59329dc9b92086b3dc619f31cef4a0c802f10829b575a3666d48a48387d" +version = "0.4.2" dependencies = [ + "ark-serialize-derive", "ark-std", + "digest 0.10.7", + "num-bigint 0.4.4", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "ark-std" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5b856a29bea7b810858116a596beee3d20fc4c5aeb240e8e5a8bca4845a470" +version = "0.4.0" dependencies = [ + "num-traits", "rand 0.7.3", - "rand_xorshift", ] [[package]] @@ -451,8 +488,11 @@ name = "concordium_base" version = "3.2.0" dependencies = [ "anyhow", + "ark-bls12-381", "ark-ec", "ark-ff", + "ark-serialize", + "ark-std", "bs58", "bulletproofs", "byteorder", @@ -467,7 +507,7 @@ dependencies = [ "ff", "group", "hex", - "itertools", + "itertools 0.10.5", "leb128", "libc", "merlin", @@ -654,7 +694,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.0", + "rustc_version", "syn 1.0.109", ] @@ -840,6 +880,10 @@ name = "hashbrown" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +dependencies = [ + "ahash 0.8.3", + "allocator-api2", +] [[package]] name = "hermit-abi" @@ -940,6 +984,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -1184,21 +1237,16 @@ dependencies = [ ] [[package]] -name = "peeking_take_while" -version = "0.1.2" +name = "paste" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] -name = "pest" -version = "2.7.5" +name = "peeking_take_while" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "ppv-lite86" @@ -1447,22 +1495,13 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.19", + "semver", ] [[package]] @@ -1483,30 +1522,12 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" version = "1.0.188" @@ -1779,12 +1800,6 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - [[package]] name = "unicode-ident" version = "1.0.12" diff --git a/mobile_wallet/Cargo.lock b/mobile_wallet/Cargo.lock index cde45038e..4d6fcb91d 100644 --- a/mobile_wallet/Cargo.lock +++ b/mobile_wallet/Cargo.lock @@ -15,13 +15,14 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -33,6 +34,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -48,41 +55,54 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + [[package]] name = "ark-ec" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56006994f509d76fbce6f6ffe3108f7191b4f3754ecd00bbae7cac20ec05020" +version = "0.4.2" dependencies = [ "ark-ff", + "ark-poly", "ark-serialize", "ark-std", "derivative", + "hashbrown 0.14.3", + "itertools 0.12.0", + "num-bigint 0.4.3", "num-traits", "zeroize", ] [[package]] name = "ark-ff" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d8802d40fce9212c5c09be08f75c4b3becc0c488e87f60fff787b01250ce33" +version = "0.4.2" dependencies = [ "ark-ff-asm", "ark-ff-macros", "ark-serialize", "ark-std", + "arrayvec", "derivative", + "digest 0.10.6", + "itertools 0.12.0", + "num-bigint 0.4.3", "num-traits", - "rustc_version 0.3.3", + "paste", + "rustc_version", "zeroize", ] [[package]] name = "ark-ff-asm" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e8cb28c2137af1ef058aa59616db3f7df67dbb70bf2be4ee6920008cc30d98c" +version = "0.4.2" dependencies = [ "quote", "syn 1.0.109", @@ -90,33 +110,51 @@ dependencies = [ [[package]] name = "ark-ff-macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9c256a93a10ed9708c16a517d6dcfaba3d215c0d7fab44d29a9affefb5eeb8" +version = "0.4.2" dependencies = [ "num-bigint 0.4.3", "num-traits", + "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "ark-poly" +version = "0.4.2" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.14.3", +] + [[package]] name = "ark-serialize" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e9b59329dc9b92086b3dc619f31cef4a0c802f10829b575a3666d48a48387d" +version = "0.4.2" dependencies = [ + "ark-serialize-derive", "ark-std", + "digest 0.10.6", + "num-bigint 0.4.3", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "ark-std" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5b856a29bea7b810858116a596beee3d20fc4c5aeb240e8e5a8bca4845a470" +version = "0.4.0" dependencies = [ + "num-traits", "rand 0.7.3", - "rand_xorshift", ] [[package]] @@ -388,8 +426,11 @@ name = "concordium_base" version = "3.2.0" dependencies = [ "anyhow", + "ark-bls12-381", "ark-ec", "ark-ff", + "ark-serialize", + "ark-std", "bs58", "bulletproofs", "byteorder", @@ -404,7 +445,7 @@ dependencies = [ "ff", "group", "hex", - "itertools", + "itertools 0.10.5", "leb128", "libc", "merlin", @@ -636,7 +677,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.0", + "rustc_version", "syn 1.0.109", ] @@ -805,7 +846,17 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash 0.8.6", + "allocator-api2", ] [[package]] @@ -891,6 +942,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.5" @@ -1191,6 +1251,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "pbkdf2" version = "0.10.1" @@ -1203,17 +1269,6 @@ dependencies = [ "sha2 0.10.6", ] -[[package]] -name = "pest" -version = "2.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1438,22 +1493,13 @@ dependencies = [ "serde_json", ] -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.16", + "semver", ] [[package]] @@ -1489,30 +1535,12 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" version = "1.0.164" @@ -1764,12 +1792,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - [[package]] name = "unicode-ident" version = "1.0.6" @@ -1923,6 +1945,26 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "zerocopy" +version = "0.7.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "zeroize" version = "1.3.0" diff --git a/rust-bins/Cargo.lock b/rust-bins/Cargo.lock index 63ce511ef..6c970ad3c 100644 --- a/rust-bins/Cargo.lock +++ b/rust-bins/Cargo.lock @@ -59,6 +59,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -89,41 +95,54 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + [[package]] name = "ark-ec" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56006994f509d76fbce6f6ffe3108f7191b4f3754ecd00bbae7cac20ec05020" +version = "0.4.2" dependencies = [ "ark-ff", + "ark-poly", "ark-serialize", "ark-std", "derivative", + "hashbrown 0.14.1", + "itertools 0.12.0", + "num-bigint 0.4.4", "num-traits", "zeroize", ] [[package]] name = "ark-ff" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d8802d40fce9212c5c09be08f75c4b3becc0c488e87f60fff787b01250ce33" +version = "0.4.2" dependencies = [ "ark-ff-asm", "ark-ff-macros", "ark-serialize", "ark-std", + "arrayvec", "derivative", + "digest 0.10.7", + "itertools 0.12.0", + "num-bigint 0.4.4", "num-traits", - "rustc_version 0.3.3", + "paste", + "rustc_version", "zeroize", ] [[package]] name = "ark-ff-asm" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e8cb28c2137af1ef058aa59616db3f7df67dbb70bf2be4ee6920008cc30d98c" +version = "0.4.2" dependencies = [ "quote", "syn 1.0.109", @@ -131,33 +150,51 @@ dependencies = [ [[package]] name = "ark-ff-macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9c256a93a10ed9708c16a517d6dcfaba3d215c0d7fab44d29a9affefb5eeb8" +version = "0.4.2" dependencies = [ "num-bigint 0.4.4", "num-traits", + "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "ark-poly" +version = "0.4.2" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.14.1", +] + [[package]] name = "ark-serialize" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e9b59329dc9b92086b3dc619f31cef4a0c802f10829b575a3666d48a48387d" +version = "0.4.2" dependencies = [ + "ark-serialize-derive", "ark-std", + "digest 0.10.7", + "num-bigint 0.4.4", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "ark-std" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5b856a29bea7b810858116a596beee3d20fc4c5aeb240e8e5a8bca4845a470" +version = "0.4.0" dependencies = [ + "num-traits", "rand 0.7.3", - "rand_xorshift", ] [[package]] @@ -490,8 +527,11 @@ version = "3.2.0" dependencies = [ "aes", "anyhow", + "ark-bls12-381", "ark-ec", "ark-ff", + "ark-serialize", + "ark-std", "base64", "bs58", "bulletproofs", @@ -509,7 +549,7 @@ dependencies = [ "group", "hex", "hmac", - "itertools", + "itertools 0.10.5", "leb128", "libc", "merlin", @@ -745,7 +785,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.0", + "rustc_version", "syn 1.0.109", ] @@ -1076,6 +1116,10 @@ name = "hashbrown" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +dependencies = [ + "ahash 0.8.3", + "allocator-api2", +] [[package]] name = "heck" @@ -1291,6 +1335,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -1766,6 +1819,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "pbkdf2" version = "0.10.1" @@ -1796,17 +1855,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" -[[package]] -name = "pest" -version = "2.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - [[package]] name = "pin-project-lite" version = "0.2.13" @@ -2163,22 +2211,13 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.19", + "semver", ] [[package]] @@ -2244,30 +2283,12 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" version = "1.0.188" @@ -2717,12 +2738,6 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - [[package]] name = "unicode-bidi" version = "0.3.13" diff --git a/rust-src/Cargo.lock b/rust-src/Cargo.lock index 45c3fefdc..16126efd9 100644 --- a/rust-src/Cargo.lock +++ b/rust-src/Cargo.lock @@ -60,6 +60,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -90,8 +96,6 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "ark-bls12-381" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" dependencies = [ "ark-ec", "ark-ff", @@ -102,16 +106,15 @@ dependencies = [ [[package]] name = "ark-ec" version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ "ark-ff", "ark-poly", "ark-serialize", "ark-std", "derivative", - "hashbrown 0.13.2", - "itertools", + "hashbrown 0.14.0", + "itertools 0.12.0", + "num-bigint 0.4.4", "num-traits", "zeroize", ] @@ -119,16 +122,15 @@ dependencies = [ [[package]] name = "ark-ff" version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ "ark-ff-asm", "ark-ff-macros", "ark-serialize", "ark-std", + "arrayvec", "derivative", "digest 0.10.7", - "itertools", + "itertools 0.12.0", "num-bigint 0.4.4", "num-traits", "paste", @@ -139,8 +141,6 @@ dependencies = [ [[package]] name = "ark-ff-asm" version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ "quote", "syn 1.0.109", @@ -149,8 +149,6 @@ dependencies = [ [[package]] name = "ark-ff-macros" version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ "num-bigint 0.4.4", "num-traits", @@ -162,21 +160,17 @@ dependencies = [ [[package]] name = "ark-poly" version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" dependencies = [ "ark-ff", "ark-serialize", "ark-std", "derivative", - "hashbrown 0.13.2", + "hashbrown 0.14.0", ] [[package]] name = "ark-serialize" version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-serialize-derive", "ark-std", @@ -187,8 +181,6 @@ dependencies = [ [[package]] name = "ark-serialize-derive" version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ "proc-macro2", "quote", @@ -198,11 +190,9 @@ dependencies = [ [[package]] name = "ark-std" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.7.3", ] [[package]] @@ -583,6 +573,8 @@ dependencies = [ "ark-bls12-381", "ark-ec", "ark-ff", + "ark-serialize", + "ark-std", "base64", "bs58", "bulletproofs", @@ -601,7 +593,7 @@ dependencies = [ "group", "hex", "hmac", - "itertools", + "itertools 0.10.5", "leb128", "libc", "merlin", @@ -677,7 +669,7 @@ dependencies = [ "ciborium", "clap", "criterion-plot", - "itertools", + "itertools 0.10.5", "lazy_static", "num-traits", "oorandom", @@ -698,7 +690,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -1074,6 +1066,10 @@ name = "hashbrown" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +dependencies = [ + "ahash 0.8.3", + "allocator-api2", +] [[package]] name = "hermit-abi" @@ -1213,6 +1209,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" diff --git a/rust-src/concordium_base/Cargo.toml b/rust-src/concordium_base/Cargo.toml index 6d130a16a..f159a0559 100644 --- a/rust-src/concordium_base/Cargo.toml +++ b/rust-src/concordium_base/Cargo.toml @@ -13,9 +13,11 @@ homepage = "https://github.com/Concordium/concordium-base" [dependencies] ff = "0.5" -ark-ff = "0.4" -ark-ec = "0.4" -ark-bls12-381 = "0.4.0" +ark-ff = { path = "../../../ark-algebra/ff", version = "0.4"} +ark-ec = { path = "../../../ark-algebra/ec", version = "0.4"} +ark-serialize = { path = "../../../ark-algebra/serialize", version = "0.4"} +ark-std = { path = "../../../ark-std", version = "0.4"} +ark-bls12-381 = { path = "../../../ark-curves/bls12_381", version = "0.4"} sha2 = "0.10" sha3 = "0.10" anyhow = "1.0" diff --git a/rust-src/concordium_base/benches/range_proof_bench.rs b/rust-src/concordium_base/benches/range_proof_bench.rs index 8ab9ffd89..6787b4914 100644 --- a/rust-src/concordium_base/benches/range_proof_bench.rs +++ b/rust-src/concordium_base/benches/range_proof_bench.rs @@ -135,6 +135,6 @@ criterion_group!( prove_verify_benchmarks::, prove_verify_benchmarks::, prove_verify_benchmarks::, - //prove_verify_benchmarks::> + prove_verify_benchmarks::> ); criterion_main!(benchmarks); diff --git a/rust-src/concordium_base/src/bulletproofs/range_proof.rs b/rust-src/concordium_base/src/bulletproofs/range_proof.rs index ae46f29e4..a2abab43c 100644 --- a/rust-src/concordium_base/src/bulletproofs/range_proof.rs +++ b/rust-src/concordium_base/src/bulletproofs/range_proof.rs @@ -803,6 +803,8 @@ pub fn verify_in_range( #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; use pairing::bls12_381::G1; @@ -811,7 +813,10 @@ mod tests { /// The second check will fail. /// This is tested by checking if the verifier returns /// Err(Err(VerificationError::Second)) - type SomeCurve = curve25519_dalek::ristretto::RistrettoPoint; + + // type SomeCurve = curve25519_dalek::ristretto::RistrettoPoint; + type SomeCurve = ArkGroup; + #[allow(non_snake_case)] #[allow(clippy::too_many_arguments)] #[allow(clippy::many_single_char_names)] @@ -983,6 +988,7 @@ mod tests { for &v in v_vec.iter().take(m.into()) { let r = Randomness::generate(rng); let v_scalar = SomeCurve::scalar_from_u64(v); + // println!("{:?}", v); let v_value = Value::::new(v_scalar); let com = keys.hide(&v_value, &r); randomness.push(r); @@ -1000,6 +1006,7 @@ mod tests { &keys, &randomness, ); + println!("{:?}", proof); assert!(proof.is_some()); let proof = proof.unwrap(); let mut transcript = RandomOracle::empty(); diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index ceb7c40f2..99003d819 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -1,12 +1,10 @@ -// use ark_ec::AffineCurve; -// use ark_ff::{FpParameters, FromBytes}; use core::fmt; -use ark_ff::BigInteger; - use crate::common::{Deserial, Serial}; use super::{Curve, CurveDecodingError, Field, GenericMultiExp, PrimeField}; +use anyhow::anyhow; +use ark_ec::{hashing::HashToCurve, AffineRepr}; #[derive(PartialEq, Eq, Copy, Clone, fmt::Debug)] pub struct ArkField(F); @@ -16,12 +14,17 @@ impl From for ArkField { } impl Serial for ArkField { - fn serial(&self, _out: &mut B) { todo!() } + fn serial(&self, out: &mut B) { + self.0 + .serialize_compressed(out) + .expect("Serialzation expected to succeed") + } } impl Deserial for ArkField { - fn deserial(_source: &mut R) -> crate::common::ParseResult { - todo!() + fn deserial(source: &mut R) -> crate::common::ParseResult { + let res = F::deserialize_compressed(source)?; + Ok(res.into()) } } @@ -32,89 +35,82 @@ impl fmt::Display for ArkField { } impl Field for ArkField { - fn random(_rng: &mut R) -> Self { todo!() } + fn random(rng: &mut R) -> Self { + F::rand(rng).into() + } fn zero() -> Self { F::zero().into() } - fn one() -> Self { todo!() } + fn one() -> Self { F::one().into() } - fn is_zero(&self) -> bool { todo!() } + fn is_zero(&self) -> bool { F::is_zero(&self.0) } - fn square(&mut self) { todo!() } + fn square(&mut self) { self.0.square_in_place(); } - fn double(&mut self) { todo!() } + fn double(&mut self) { self.0.double_in_place(); } - fn negate(&mut self) { todo!() } + fn negate(&mut self) { self.0.neg_in_place(); } - fn add_assign(&mut self, _other: &Self) { todo!() } + fn add_assign(&mut self, other: &Self) { self.0 += other.0 } - fn sub_assign(&mut self, _other: &Self) { todo!() } + fn sub_assign(&mut self, other: &Self) { self.0 -= other.0 } - fn mul_assign(&mut self, _other: &Self) { todo!() } + fn mul_assign(&mut self, other: &Self) { self.0 *= other.0 } - fn inverse(&self) -> Option { todo!() } + fn inverse(&self) -> Option { self.0.inverse().map(|x| x.into()) } } impl PrimeField for ArkField { const CAPACITY: u32 = Self::NUM_BITS - 1; const NUM_BITS: u32 = F::MODULUS_BIT_SIZE; - fn into_repr(self) -> Vec { - self.0.into_bigint().as_ref().to_vec() - // self.0.into_repr().as_ref().to_vec() - } + fn into_repr(self) -> Vec { self.0.into_bigint().as_ref().to_vec() } fn from_repr(repr: &[u64]) -> Result { - // let mut buffer = Vec::new(); - // for u in repr { - // buffer.extend(u.to_le_bytes()); - // } - // let big_int = F::BigInt::read(buffer.as_slice()) - // .map_err(|_| CurveDecodingError::NotInField(format!("{:?}", repr)))?; - // let res = - // F::from_repr(big_int).ok_or(CurveDecodingError::NotInField(format!("{:?}" - // , repr)))?; Ok(ArkField(res)) - todo!() + let mut buffer = Vec::new(); + for u in repr { + buffer.extend(u.to_le_bytes()); + } + + let big_int = num_bigint::BigUint::from_bytes_le(&buffer) + .try_into() + .map_err(|_| CurveDecodingError::NotInField(format!("{:?}", repr)))?; + let res = + F::from_bigint(big_int).ok_or(CurveDecodingError::NotInField(format!("{:?}", repr)))?; + Ok(res.into()) } } #[derive(PartialEq, Eq, Copy, Clone, fmt::Debug)] -pub struct ArkGroup< - G: ark_ec::CurveGroup + Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display, ->(G); - -impl< - G: ark_ec::CurveGroup + Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display, - > Serial for ArkGroup -{ - fn serial(&self, _out: &mut B) { todo!() } +pub struct ArkGroup(G); + +impl Serial for ArkGroup { + fn serial(&self, out: &mut B) { + self.0 + .serialize_compressed(out) + .expect("Serialzation expected to succeed") + } } -impl< - G: ark_ec::CurveGroup + Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display, - > Deserial for ArkGroup -{ - fn deserial(_source: &mut R) -> crate::common::ParseResult { - todo!() +impl Deserial for ArkGroup { + fn deserial(source: &mut R) -> crate::common::ParseResult { + let res = G::deserialize_compressed(source)?; + Ok(ArkGroup(res)) } } -impl< - G: ark_ec::CurveGroup + Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display, - > From for ArkGroup -{ +impl From for ArkGroup { fn from(value: G) -> Self { ArkGroup(value) } } -pub(crate) trait ArkCurveConfig { +pub(crate) trait ArkCurveConfig { const SCALAR_LENGTH: usize; const GROUP_ELEMENT_LENGTH: usize; - const DOMAIN_STRING: String; + const DOMAIN_STRING: &'static str; + type Hasher: ark_ec::hashing::HashToCurve; } -impl + ArkCurveConfig> Curve - for ArkGroup -{ +impl> Curve for ArkGroup { type MultiExpType = GenericMultiExp; type Scalar = ArkField; @@ -135,38 +131,36 @@ impl + ArkCurveConfig> C fn minus_point(&self, other: &Self) -> Self { ArkGroup(self.0 - other.0) } - fn mul_by_scalar(&self, scalar: &Self::Scalar) -> Self { - // ArkGroup(self.0.into_affine().mul(scalar.0)) - ArkGroup(self.0 * scalar.0) - } - - fn bytes_to_curve_unchecked(_b: &mut R) -> anyhow::Result { - todo!() + fn mul_by_scalar(&self, scalar: &Self::Scalar) -> Self { ArkGroup(self.0 * scalar.0) } + + fn bytes_to_curve_unchecked(b: &mut R) -> anyhow::Result { + // TODO: this implementation is not efficient. + let mut buffer = Vec::new(); + b.read(&mut buffer)?; + // In fact, `from_random_bytes` checks if the bytes correspond to a valid group + // element. It seems like there is no unchecked methods exposed through + // ark traits. + let res = G::Affine::from_random_bytes(&buffer) + .ok_or(anyhow!("Expected a valid group element"))?; + Ok(ArkGroup(res.into())) } - fn generate(rng: &mut R) -> Self { - todo!() - // ArkGroup(G::rand(rng)) - } + fn generate(rng: &mut R) -> Self { ArkGroup(G::rand(rng)) } fn generate_scalar(rng: &mut R) -> Self::Scalar { - // ArkField(::rand(rng)) - todo!() + ::rand(rng).into() } fn scalar_from_u64(n: u64) -> Self::Scalar { ArkField(G::ScalarField::from(n)) } fn scalar_from_bytes>(bs: A) -> Self::Scalar { - let res = ::from_random_bytes(bs.as_ref()) - .expect("Input bytes must be a valid scalar values"); - ArkField(res) + ::from_le_bytes_mod_order(bs.as_ref()).into() } fn hash_to_group(m: &[u8]) -> Self { - let hasher = - G::new(G::DOMAIN_STRING.as_ref()).expect("Expected valid domain separation string"); - let res = >::hash(&hasher, &m) - .expect("Expected successful hashing to curve"); + let hasher = G::Hasher::new(G::DOMAIN_STRING.as_ref()) + .expect("Expected valid domain separation string"); + let res = G::Hasher::hash(&hasher, &m).expect("Expected successful hashing to curve"); ArkGroup(res.into()) } } diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs new file mode 100644 index 000000000..d13c87f89 --- /dev/null +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -0,0 +1,45 @@ +use ark_bls12_381::*; +use ark_ec::hashing::{curve_maps::wb::WBMap, map_to_curve_hasher::MapToCurveBasedHasher}; +use ark_ff::{field_hashers::DefaultFieldHasher, BigInt}; +use sha2::Sha256; + +use crate::common::{Serial, Buffer}; + +use super::arkworks_instances::ArkCurveConfig; + +impl ArkCurveConfig for G1Projective { + type Hasher = + MapToCurveBasedHasher, WBMap>; + + const DOMAIN_STRING: &'static str = ""; + const GROUP_ELEMENT_LENGTH: usize = 64; + const SCALAR_LENGTH: usize = 32; +} + +/// This implementation is ad-hoc, using the fact that Fq12 is defined +/// via that specific tower of extensions (of degrees) 2 -> 3 -> 2, +/// and the specific representation of those fields. +/// We use big-endian representation all the way down to the field Fq. +impl Serial for Fq12 { + fn serial(&self, out: &mut B) { + // coefficients in the extension F_6 + let c0_6 = self.c0; + let c1_6 = self.c1; + + let coeffs = [ + // coefficients of c1_6 in the extension F_2 + c1_6.c2, c1_6.c1, c1_6.c0, // coefficients of c0_6 in the extension F_2 + c0_6.c2, c0_6.c1, c0_6.c0, + ]; + for p in coeffs.iter() { + let repr_c1: BigInt<6> = Fq::from(p.c1).into(); + let repr_c0: BigInt<6> = Fq::from(p.c0).into(); + for d in repr_c1.0.iter() { + d.serial(out); + } + for d in repr_c0.0.iter() { + d.serial(out); + } + } + } +} \ No newline at end of file diff --git a/rust-src/concordium_base/src/curve_arithmetic/ed25519_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/ed25519_arkworks.rs index eab28dab6..ff3475cca 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/ed25519_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/ed25519_arkworks.rs @@ -2,6 +2,6 @@ use super::arkworks_instances::CurveElementLength; use ark_curve25519::*; impl CurveElementLength for EdwardsProjective { - const GROUP_ELEMENT_LENGTH: usize = 64; + const GROUP_ELEMENT_LENGTH: usize = 32; const SCALAR_LENGTH: usize = 32; } diff --git a/rust-src/concordium_base/src/curve_arithmetic/mod.rs b/rust-src/concordium_base/src/curve_arithmetic/mod.rs index 9d0c49181..02364e989 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/mod.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/mod.rs @@ -5,6 +5,7 @@ mod bls12_381_g1hash; mod bls12_381_g2hash; mod bls12_381_instance; // mod ed25519_arkworks; +mod bls12_381_arkworks; mod ed25519_instance; mod ed25519_ng_instance; // mod ed25519_new_instance; From 3a3c3c49066ac0bbeb42473635cbfaaa9e2f1ed8 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 11 Dec 2023 09:11:09 +0100 Subject: [PATCH 04/53] Remove pairing; replace it with arkworks bls implementation --- identity-provider-service/Cargo.lock | 2 +- idiss/Cargo.lock | 2 +- mobile_wallet/Cargo.lock | 2 +- rust-bins/Cargo.lock | 2 +- rust-src/Cargo.lock | 2 +- rust-src/concordium_base/Cargo.toml | 2 +- .../concordium_base/src/aggregate_sig/ffi.rs | 8 +- .../concordium_base/src/aggregate_sig/mod.rs | 5 +- .../src/bulletproofs/inner_product_proof.rs | 7 +- .../src/bulletproofs/range_proof.rs | 1 - .../src/bulletproofs/set_membership_proof.rs | 21 ++- .../bulletproofs/set_non_membership_proof.rs | 21 ++- .../concordium_base/src/bulletproofs/utils.rs | 5 +- rust-src/concordium_base/src/common/impls.rs | 137 ------------------ .../curve_arithmetic/arkworks_instances.rs | 19 ++- .../curve_arithmetic/bls12_381_arkworks.rs | 96 +++++++++++- .../src/curve_arithmetic/ed25519_instance.rs | 10 +- .../curve_arithmetic/ed25519_ng_instance.rs | 10 +- .../src/curve_arithmetic/mod.rs | 18 ++- .../src/curve_arithmetic/secret_value.rs | 21 ++- .../src/dodis_yampolskiy_prf/secret.rs | 8 +- .../concordium_base/src/elgamal/cipher.rs | 8 +- .../concordium_base/src/elgamal/message.rs | 13 +- rust-src/concordium_base/src/elgamal/mod.rs | 22 ++- .../concordium_base/src/elgamal/public.rs | 9 +- .../concordium_base/src/elgamal/secret.rs | 21 ++- .../src/encrypted_transfers/ffi.rs | 5 +- .../src/encrypted_transfers/mod.rs | 23 +-- .../proofs/generate_proofs.rs | 16 +- .../concordium_base/src/id/account_holder.rs | 17 ++- rust-src/concordium_base/src/id/chain.rs | 11 +- rust-src/concordium_base/src/id/constants.rs | 23 +-- rust-src/concordium_base/src/id/ffi.rs | 6 +- .../concordium_base/src/id/id_proof_types.rs | 6 +- .../concordium_base/src/id/id_verifier.rs | 5 +- .../src/id/identity_provider.rs | 1 - .../concordium_base/src/id/secret_sharing.rs | 12 +- rust-src/concordium_base/src/id/test.rs | 2 +- rust-src/concordium_base/src/id/utils.rs | 8 +- .../src/pedersen_commitment/commitment.rs | 7 +- .../src/pedersen_commitment/key.rs | 20 ++- .../src/pedersen_commitment/randomness.rs | 17 ++- .../src/ps_sig/known_message.rs | 3 +- rust-src/concordium_base/src/ps_sig/public.rs | 2 +- rust-src/concordium_base/src/ps_sig/secret.rs | 2 +- .../concordium_base/src/ps_sig/signature.rs | 2 +- .../src/ps_sig/unknown_message.rs | 2 +- .../src/sigma_protocols/aggregate_dlog.rs | 6 +- .../src/sigma_protocols/com_enc_eq.rs | 6 +- .../src/sigma_protocols/com_eq.rs | 7 +- .../com_eq_different_groups.rs | 7 +- .../src/sigma_protocols/com_eq_sig.rs | 12 +- .../src/sigma_protocols/com_ineq.rs | 9 +- .../src/sigma_protocols/com_lin.rs | 12 +- .../src/sigma_protocols/com_mult.rs | 6 +- .../src/sigma_protocols/dlog.rs | 6 +- .../src/sigma_protocols/dlogaggequal.rs | 13 +- .../src/sigma_protocols/dlogeq.rs | 13 +- .../src/sigma_protocols/enc_trans.rs | 5 +- .../src/sigma_protocols/sigma_test.rs | 7 +- .../src/sigma_protocols/vcom_eq.rs | 6 +- 61 files changed, 467 insertions(+), 310 deletions(-) diff --git a/identity-provider-service/Cargo.lock b/identity-provider-service/Cargo.lock index 170b95a90..adacf68bd 100644 --- a/identity-provider-service/Cargo.lock +++ b/identity-provider-service/Cargo.lock @@ -530,7 +530,6 @@ dependencies = [ "num", "num-bigint 0.4.4", "num-traits", - "pairing", "rand 0.7.3", "rand_core 0.5.1", "rayon", @@ -539,6 +538,7 @@ dependencies = [ "serde_json", "serde_with", "sha2 0.10.8", + "sha2 0.9.9", "sha3 0.10.8", "subtle", "thiserror", diff --git a/idiss/Cargo.lock b/idiss/Cargo.lock index 70dcadcbc..d77cbee89 100644 --- a/idiss/Cargo.lock +++ b/idiss/Cargo.lock @@ -515,7 +515,6 @@ dependencies = [ "num", "num-bigint 0.4.4", "num-traits", - "pairing", "rand 0.7.3", "rand_core 0.5.1", "rayon", @@ -524,6 +523,7 @@ dependencies = [ "serde_json", "serde_with", "sha2 0.10.8", + "sha2 0.9.9", "sha3 0.10.8", "subtle", "thiserror", diff --git a/mobile_wallet/Cargo.lock b/mobile_wallet/Cargo.lock index 4d6fcb91d..887661f06 100644 --- a/mobile_wallet/Cargo.lock +++ b/mobile_wallet/Cargo.lock @@ -453,7 +453,6 @@ dependencies = [ "num", "num-bigint 0.4.3", "num-traits", - "pairing", "rand 0.7.3", "rand_core 0.5.1", "rayon", @@ -462,6 +461,7 @@ dependencies = [ "serde_json", "serde_with", "sha2 0.10.6", + "sha2 0.9.9", "sha3 0.10.6", "subtle", "thiserror", diff --git a/rust-bins/Cargo.lock b/rust-bins/Cargo.lock index 6c970ad3c..2f66e01e7 100644 --- a/rust-bins/Cargo.lock +++ b/rust-bins/Cargo.lock @@ -557,7 +557,6 @@ dependencies = [ "num", "num-bigint 0.4.4", "num-traits", - "pairing", "pbkdf2 0.11.0", "rand 0.7.3", "rand_core 0.5.1", @@ -567,6 +566,7 @@ dependencies = [ "serde_json", "serde_with", "sha2 0.10.8", + "sha2 0.9.9", "sha3 0.10.8", "subtle", "thiserror", diff --git a/rust-src/Cargo.lock b/rust-src/Cargo.lock index 16126efd9..7f1b7feb7 100644 --- a/rust-src/Cargo.lock +++ b/rust-src/Cargo.lock @@ -601,7 +601,6 @@ dependencies = [ "num", "num-bigint 0.4.4", "num-traits", - "pairing", "pbkdf2 0.11.0", "pprof", "rand 0.7.3", @@ -612,6 +611,7 @@ dependencies = [ "serde_json", "serde_with", "sha2 0.10.7", + "sha2 0.9.9", "sha3 0.10.8", "subtle", "thiserror", diff --git a/rust-src/concordium_base/Cargo.toml b/rust-src/concordium_base/Cargo.toml index f159a0559..ad8f950d9 100644 --- a/rust-src/concordium_base/Cargo.toml +++ b/rust-src/concordium_base/Cargo.toml @@ -19,6 +19,7 @@ ark-serialize = { path = "../../../ark-algebra/serialize", version = "0.4"} ark-std = { path = "../../../ark-std", version = "0.4"} ark-bls12-381 = { path = "../../../ark-curves/bls12_381", version = "0.4"} sha2 = "0.10" +sha2-old = { version = "0.9", package = "sha2" } sha3 = "0.10" anyhow = "1.0" rand_core = "=0.5" @@ -32,7 +33,6 @@ byteorder = "1.3" hex = "0.4" itertools = "0.10" either = "1.6" -pairing = "0.15" derive_more = "0.99" thiserror = "1.0" rand = "0.7" diff --git a/rust-src/concordium_base/src/aggregate_sig/ffi.rs b/rust-src/concordium_base/src/aggregate_sig/ffi.rs index 27a0d2042..3d4be223a 100644 --- a/rust-src/concordium_base/src/aggregate_sig/ffi.rs +++ b/rust-src/concordium_base/src/aggregate_sig/ffi.rs @@ -1,11 +1,15 @@ #![cfg(feature = "ffi")] use super::*; -use crate::{common::*, ffi_helpers::*, random_oracle::RandomOracle, sigma_protocols::dlog}; -use pairing::bls12_381::Bls12; +use crate::{ + common::*, curve_arithmetic::arkworks_instances::ArkGroup, ffi_helpers::*, + random_oracle::RandomOracle, sigma_protocols::dlog, +}; use rand::{rngs::StdRng, thread_rng, SeedableRng}; use std::{cmp::Ordering, slice}; +type Bls12 = ark_ec::bls12::Bls12; + #[no_mangle] #[allow(clippy::not_unsafe_ptr_arg_deref)] pub extern "C" fn bls_generate_secretkey() -> *mut SecretKey { diff --git a/rust-src/concordium_base/src/aggregate_sig/mod.rs b/rust-src/concordium_base/src/aggregate_sig/mod.rs index 0b1566f32..0a4ea9cec 100644 --- a/rust-src/concordium_base/src/aggregate_sig/mod.rs +++ b/rust-src/concordium_base/src/aggregate_sig/mod.rs @@ -280,14 +280,17 @@ fn hash_message(m: &[u8]) -> Output { Sha512::digest(m) } #[cfg(test)] mod test { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::Bls12; use rand::{rngs::StdRng, thread_rng, SeedableRng}; use std::convert::TryFrom; const SIGNERS: usize = 500; const TEST_ITERATIONS: usize = 10; + type Bls12 = ark_ec::bls12::Bls12; + // returns a pair of lists (sks, pks), such that sks[i] and pks[i] are // corresponding secret and public key fn get_sks_pks( diff --git a/rust-src/concordium_base/src/bulletproofs/inner_product_proof.rs b/rust-src/concordium_base/src/bulletproofs/inner_product_proof.rs index 7addcb249..9163c7e2c 100644 --- a/rust-src/concordium_base/src/bulletproofs/inner_product_proof.rs +++ b/rust-src/concordium_base/src/bulletproofs/inner_product_proof.rs @@ -458,11 +458,12 @@ pub fn inner_product(a: &[F], b: &[F]) -> F { #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use crate::curve_arithmetic::Curve; - use pairing::bls12_381::G1; + use ark_bls12_381::G1Projective; use rand::thread_rng; - type SomeCurve = G1; + type SomeCurve = ArkGroup; #[test] fn testinner() { diff --git a/rust-src/concordium_base/src/bulletproofs/range_proof.rs b/rust-src/concordium_base/src/bulletproofs/range_proof.rs index a2abab43c..7ea7d375f 100644 --- a/rust-src/concordium_base/src/bulletproofs/range_proof.rs +++ b/rust-src/concordium_base/src/bulletproofs/range_proof.rs @@ -806,7 +806,6 @@ mod tests { use crate::curve_arithmetic::arkworks_instances::ArkGroup; use super::*; - use pairing::bls12_381::G1; /// This function produces a proof that will satisfy the verifier's first /// check, even if the values are not in the interval. diff --git a/rust-src/concordium_base/src/bulletproofs/set_membership_proof.rs b/rust-src/concordium_base/src/bulletproofs/set_membership_proof.rs index 8b32c184b..e37277134 100644 --- a/rust-src/concordium_base/src/bulletproofs/set_membership_proof.rs +++ b/rust-src/concordium_base/src/bulletproofs/set_membership_proof.rs @@ -563,9 +563,12 @@ pub fn verify( #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::G1; - type SomeCurve = G1; + use ark_bls12_381::G1Projective; + + type SomeCurve = ArkGroup; /// Converts the u64 set vector into a vector over the field fn get_set_vector(the_set: &[u64]) -> Vec { @@ -573,7 +576,13 @@ mod tests { } /// generates several values used in tests - fn generate_helper_values(n: usize) -> (Generators, CommitmentKey, Randomness) { + fn generate_helper_values( + n: usize, + ) -> ( + Generators, + CommitmentKey, + Randomness, + ) { let rng = &mut thread_rng(); let gens = Generators::generate(n, rng); let b = SomeCurve::generate(rng); @@ -587,9 +596,9 @@ mod tests { /// Generates commitment to v given commitment key and randomness fn get_v_com( v: &::Scalar, - v_keys: &CommitmentKey, - v_rand: &Randomness, - ) -> Commitment { + v_keys: &CommitmentKey, + v_rand: &Randomness, + ) -> Commitment { let v_value = Value::::new(*v); v_keys.hide(&v_value, &v_rand) diff --git a/rust-src/concordium_base/src/bulletproofs/set_non_membership_proof.rs b/rust-src/concordium_base/src/bulletproofs/set_non_membership_proof.rs index 251f9f54e..fb89af25e 100644 --- a/rust-src/concordium_base/src/bulletproofs/set_non_membership_proof.rs +++ b/rust-src/concordium_base/src/bulletproofs/set_non_membership_proof.rs @@ -493,9 +493,12 @@ pub fn verify( #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::G1; - type SomeCurve = G1; + use ark_bls12_381::G1Projective; + + type SomeCurve = ArkGroup; /// Converts the u64 set vector into a vector over the field fn get_set_vector(the_set: &[u64]) -> Vec { @@ -503,7 +506,13 @@ mod tests { } /// generates several values used in tests - fn generate_helper_values(n: usize) -> (Generators, CommitmentKey, Randomness) { + fn generate_helper_values( + n: usize, + ) -> ( + Generators, + CommitmentKey, + Randomness, + ) { let rng = &mut thread_rng(); let gens = Generators::generate(n, rng); let b = SomeCurve::generate(rng); @@ -517,9 +526,9 @@ mod tests { /// Generates commitment to v given commitment key and randomness fn get_v_com( v: &::Scalar, - v_keys: &CommitmentKey, - v_rand: &Randomness, - ) -> Commitment { + v_keys: &CommitmentKey, + v_rand: &Randomness, + ) -> Commitment { let v_value = Value::::new(*v); v_keys.hide(&v_value, &v_rand) diff --git a/rust-src/concordium_base/src/bulletproofs/utils.rs b/rust-src/concordium_base/src/bulletproofs/utils.rs index 25d6125f2..851c5b726 100644 --- a/rust-src/concordium_base/src/bulletproofs/utils.rs +++ b/rust-src/concordium_base/src/bulletproofs/utils.rs @@ -75,11 +75,12 @@ pub(crate) fn pad_vector_to_power_of_two(vec: &mut Vec) { #[cfg(test)] mod tests { + use crate::curve_arithmetic::{arkworks_instances::ArkField, Field}; + use super::{pad_vector_to_power_of_two, z_vec}; - use ff::Field; use rand::thread_rng; - type SomeField = pairing::bls12_381::Fq; + type SomeField = ArkField; #[test] fn test_vector_padding() { diff --git a/rust-src/concordium_base/src/common/impls.rs b/rust-src/concordium_base/src/common/impls.rs index 935c59e2a..74c12a465 100644 --- a/rust-src/concordium_base/src/common/impls.rs +++ b/rust-src/concordium_base/src/common/impls.rs @@ -2,11 +2,6 @@ use anyhow::bail; use byteorder::ReadBytesExt; use concordium_contracts_common::{constants::SHA256, hashes::HashBytes, NonZeroThresholdU8}; -use ff::PrimeField; -use group::{CurveAffine, CurveProjective, EncodedPoint}; -use pairing::bls12_381::{ - Fq12, FqRepr, Fr, FrRepr, G1Affine, G1Compressed, G2Affine, G2Compressed, G1, G2, -}; use std::convert::TryFrom; use super::serialize::*; @@ -22,138 +17,6 @@ impl Deserial for concordium_contracts_common::Timestamp { } } -impl Deserial for Fr { - fn deserial(source: &mut R) -> ParseResult { - let mut frrepr: FrRepr = FrRepr([0u64; 4]); - // Read the scalar in big endian. - for digit in frrepr.as_mut().iter_mut().rev() { - *digit = source.get()?; - } - Ok(Fr::from_repr(frrepr)?) - } -} - -impl Serial for Fr { - fn serial(&self, out: &mut B) { - let frpr = &self.into_repr(); - for a in frpr.as_ref().iter().rev() { - a.serial(out); - } - } -} - -impl Deserial for G1 { - fn deserial(source: &mut R) -> ParseResult { - let mut g = G1Compressed::empty(); - source.read_exact(g.as_mut())?; - Ok(g.into_affine()?.into_projective()) - } -} - -impl Serial for G1 { - fn serial(&self, out: &mut B) { - let g = self.into_affine().into_compressed(); - let g_bytes = g.as_ref(); - if let Err(e) = out.write_all(g_bytes) { - panic!( - "Precondition violated. Buffer should be safe to write {}.", - e - ); - } - } -} - -impl Deserial for G1Affine { - fn deserial(source: &mut R) -> ParseResult { - let mut g = G1Compressed::empty(); - source.read_exact(g.as_mut())?; - Ok(g.into_affine()?) - } -} - -impl Serial for G1Affine { - fn serial(&self, out: &mut B) { - let g = self.into_compressed(); - let g_bytes = g.as_ref(); - if let Err(e) = out.write_all(g_bytes) { - panic!( - "Precondition violated. Buffer should be safe to write {}.", - e - ); - } - } -} - -impl Deserial for G2 { - fn deserial(source: &mut R) -> ParseResult { - let mut g = G2Compressed::empty(); - source.read_exact(g.as_mut())?; - Ok(g.into_affine()?.into_projective()) - } -} - -impl Serial for G2 { - fn serial(&self, out: &mut B) { - let g = self.into_affine().into_compressed(); - let g_bytes = g.as_ref(); - if let Err(e) = out.write_all(g_bytes) { - panic!( - "Precondition violated. Buffer should be safe to write {}.", - e - ); - } - } -} - -impl Deserial for G2Affine { - fn deserial(source: &mut R) -> ParseResult { - let mut g = G2Compressed::empty(); - source.read_exact(g.as_mut())?; - Ok(g.into_affine()?) - } -} - -impl Serial for G2Affine { - fn serial(&self, out: &mut B) { - let g = self.into_compressed(); - let g_bytes = g.as_ref(); - if let Err(e) = out.write_all(g_bytes) { - panic!( - "Precondition violated. Buffer should be safe to write {}.", - e - ); - } - } -} - -/// This implementation is ad-hoc, using the fact that Fq12 is defined -/// via that specific tower of extensions (of degrees) 2 -> 3 -> 2, -/// and the specific representation of those fields. -/// We use big-endian representation all the way down to the field Fq. -impl Serial for Fq12 { - fn serial(&self, out: &mut B) { - // coefficients in the extension F_6 - let c0_6 = self.c0; - let c1_6 = self.c1; - - let coeffs = [ - // coefficients of c1_6 in the extension F_2 - c1_6.c2, c1_6.c1, c1_6.c0, // coefficients of c0_6 in the extension F_2 - c0_6.c2, c0_6.c1, c0_6.c0, - ]; - for p in coeffs.iter() { - let repr_c1 = FqRepr::from(p.c1); - let repr_c0 = FqRepr::from(p.c0); - for d in repr_c1.as_ref().iter() { - d.serial(out); - } - for d in repr_c0.as_ref().iter() { - d.serial(out); - } - } - } -} - // Implementations for the dalek curve. use ed25519_dalek::*; diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 99003d819..13190fda4 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -1,4 +1,5 @@ use core::fmt; +use std::str::FromStr; use crate::common::{Deserial, Serial}; @@ -6,8 +7,8 @@ use super::{Curve, CurveDecodingError, Field, GenericMultiExp, PrimeField}; use anyhow::anyhow; use ark_ec::{hashing::HashToCurve, AffineRepr}; -#[derive(PartialEq, Eq, Copy, Clone, fmt::Debug)] -pub struct ArkField(F); +#[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, fmt::Debug)] +pub struct ArkField(pub(crate) F); impl From for ArkField { fn from(value: F) -> Self { ArkField(value) } @@ -82,7 +83,11 @@ impl PrimeField for ArkField { } #[derive(PartialEq, Eq, Copy, Clone, fmt::Debug)] -pub struct ArkGroup(G); +pub struct ArkGroup(pub(crate) G); + +impl ArkGroup { + pub fn into_ark(&self) -> &G { &self.0 } +} impl Serial for ArkGroup { fn serial(&self, out: &mut B) { @@ -112,7 +117,7 @@ pub(crate) trait ArkCurveConfig { impl> Curve for ArkGroup { type MultiExpType = GenericMultiExp; - type Scalar = ArkField; + type Scalar = ArkField<::ScalarField>; const GROUP_ELEMENT_LENGTH: usize = G::GROUP_ELEMENT_LENGTH; const SCALAR_LENGTH: usize = G::SCALAR_LENGTH; @@ -164,3 +169,9 @@ impl> Curve for ArkGroup { ArkGroup(res.into()) } } + +impl FromStr for ArkField { + type Err = F::Err; + + fn from_str(s: &str) -> Result { F::from_str(s).map(|x| x.into()) } +} diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index d13c87f89..9a74f0f5b 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -1,18 +1,51 @@ use ark_bls12_381::*; -use ark_ec::hashing::{curve_maps::wb::WBMap, map_to_curve_hasher::MapToCurveBasedHasher}; +use ark_ec::{ + bls12::{G1Prepared, G2Prepared}, + hashing::{curve_maps::wb::WBMap, map_to_curve_hasher::MapToCurveBasedHasher}, + pairing::MillerLoopOutput, + short_weierstrass::Projective, + CurveGroup, +}; use ark_ff::{field_hashers::DefaultFieldHasher, BigInt}; use sha2::Sha256; -use crate::common::{Serial, Buffer}; +use crate::common::{Buffer, Serial}; -use super::arkworks_instances::ArkCurveConfig; +use super::{ + arkworks_instances::{ArkCurveConfig, ArkField, ArkGroup}, + Pairing, +}; -impl ArkCurveConfig for G1Projective { +impl ArkCurveConfig for Projective { + type Hasher = MapToCurveBasedHasher< + Projective, + DefaultFieldHasher, + WBMap, + >; + + const DOMAIN_STRING: &'static str = "BLS12381G1"; + const GROUP_ELEMENT_LENGTH: usize = 48; + const SCALAR_LENGTH: usize = 32; +} + +// impl ArkCurveConfig> for +// Projective> { type Hasher = MapToCurveBasedHasher< +// Projective>, +// DefaultFieldHasher, +// WBMap>, +// >; + +// const DOMAIN_STRING: &'static str = "BLS12381G1"; +// const GROUP_ELEMENT_LENGTH: usize = 48; +// const SCALAR_LENGTH: usize = 32; +// } + +impl ArkCurveConfig for Projective { type Hasher = - MapToCurveBasedHasher, WBMap>; + MapToCurveBasedHasher, WBMap>; - const DOMAIN_STRING: &'static str = ""; - const GROUP_ELEMENT_LENGTH: usize = 64; + const DOMAIN_STRING: &'static str = "BLS12381G2"; + const GROUP_ELEMENT_LENGTH: usize = 96; const SCALAR_LENGTH: usize = 32; } @@ -42,4 +75,51 @@ impl Serial for Fq12 { } } } -} \ No newline at end of file +} + +type Bls12 = ark_ec::bls12::Bls12; + +impl Pairing for Bls12 { + type G1 = ArkGroup<::G1>; + type G1Prepared = ::G1Prepared; + type G2 = ArkGroup<::G2>; + type G2Prepared = ::G2Prepared; + type ScalarField = ArkField; + type TargetField = ArkField<::TargetField>; + + #[inline(always)] + fn g1_prepare(g: &Self::G1) -> Self::G1Prepared { + let res: G1Prepared<_> = g.into_ark().into_affine().into(); + res.into() + } + + #[inline(always)] + fn g2_prepare(g: &Self::G2) -> Self::G2Prepared { + let res: G2Prepared<_> = g.into_ark().into_affine().into(); + res.into() + } + + #[inline(always)] + fn miller_loop<'a, I>(i: I) -> Self::TargetField + where + I: IntoIterator, { + let (xs, ys): (Vec<_>, Vec<_>) = i.into_iter().map(|x| *x).unzip(); + let res = ::multi_miller_loop( + xs.into_iter().map(|x| x.clone()), + ys.into_iter().map(|x| x.clone()), + ) + .0; + res.into() + } + + #[inline(always)] + fn final_exponentiation(x: &Self::TargetField) -> Option { + let res = ::final_exponentiation(MillerLoopOutput(x.0)); + res.map(|x| x.0.into()) + } + + #[inline(always)] + fn generate_scalar(csprng: &mut T) -> Self::ScalarField { + ::rand(csprng).into() + } +} diff --git a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs index 9f4d4050f..c9ae16d68 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs @@ -12,6 +12,8 @@ use curve25519_dalek::{ traits::Identity, }; +use sha2_old::Sha512; + use super::{Curve, Field, GenericMultiExp, PrimeField}; /// A wrapper to make it possible to implement external traits @@ -52,7 +54,7 @@ impl From for RistrettoScalar { } impl Field for RistrettoScalar { - fn random(rng: &mut R) -> Self { + fn random(rng: &mut R) -> Self { let mut scalar_bytes = [0u8; 64]; rng.fill_bytes(&mut scalar_bytes); Scalar::from_bytes_mod_order_wide(&scalar_bytes).into() @@ -197,10 +199,8 @@ impl Curve for RistrettoPoint { fn scalar_from_u64(n: u64) -> Self::Scalar { Scalar::from(n).into() } fn scalar_from_bytes>(bs: A) -> Self::Scalar { - Scalar::hash_from_bytes::(bs.as_ref()).into() + Scalar::hash_from_bytes::(bs.as_ref()).into() } - fn hash_to_group(m: &[u8]) -> Self { - RistrettoPoint::hash_from_bytes::(m) - } + fn hash_to_group(m: &[u8]) -> Self { RistrettoPoint::hash_from_bytes::(m) } } diff --git a/rust-src/concordium_base/src/curve_arithmetic/ed25519_ng_instance.rs b/rust-src/concordium_base/src/curve_arithmetic/ed25519_ng_instance.rs index d64c055ea..03b009696 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/ed25519_ng_instance.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/ed25519_ng_instance.rs @@ -12,6 +12,8 @@ use std::{ ops::{AddAssign, MulAssign, Neg, SubAssign}, }; +use sha2_old::Sha512; + use super::{Curve, Field, MultiExp, PrimeField}; /// A wrapper to make it possible to implement external traits @@ -52,7 +54,7 @@ impl From for RistrettoScalar { } impl Field for RistrettoScalar { - fn random(rng: &mut R) -> Self { + fn random(rng: &mut R) -> Self { let mut scalar_bytes = [0u8; 64]; rng.fill_bytes(&mut scalar_bytes); Scalar::from_bytes_mod_order_wide(&scalar_bytes).into() @@ -197,12 +199,10 @@ impl Curve for RistrettoPoint { fn scalar_from_u64(n: u64) -> Self::Scalar { Scalar::from(n).into() } fn scalar_from_bytes>(bs: A) -> Self::Scalar { - Scalar::hash_from_bytes::(bs.as_ref()).into() + Scalar::hash_from_bytes::(bs.as_ref()).into() } - fn hash_to_group(m: &[u8]) -> Self { - RistrettoPoint::hash_from_bytes::(m) - } + fn hash_to_group(m: &[u8]) -> Self { RistrettoPoint::hash_from_bytes::(m) } } /// An instance of multiexp algorithm from the Dalek labrary that uses diff --git a/rust-src/concordium_base/src/curve_arithmetic/mod.rs b/rust-src/concordium_base/src/curve_arithmetic/mod.rs index 02364e989..1a5d5b0d7 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/mod.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/mod.rs @@ -1,9 +1,9 @@ //! Basic definitions of the curve and pairing abstractions, and implementations //! of these abstractions for the curves used on Concordium. pub mod arkworks_instances; -mod bls12_381_g1hash; -mod bls12_381_g2hash; -mod bls12_381_instance; +// mod bls12_381_g1hash; +// mod bls12_381_g2hash; +// mod bls12_381_instance; // mod ed25519_arkworks; mod bls12_381_arkworks; mod ed25519_instance; @@ -419,8 +419,10 @@ where #[cfg(test)] mod tests { - use super::*; - use pairing::bls12_381::G1; + use super::{arkworks_instances::ArkGroup, *}; + use ark_bls12_381::G1Projective; + + type SomeCurve = ArkGroup; #[test] pub fn test_multiscalar() { @@ -429,10 +431,10 @@ mod tests { let mut gs = Vec::with_capacity(l); let mut es = Vec::with_capacity(l); for _ in 0..l { - gs.push(G1::generate(&mut csprng)); - es.push(G1::generate_scalar(&mut csprng)); + gs.push(SomeCurve::generate(&mut csprng)); + es.push(SomeCurve::generate_scalar(&mut csprng)); } - let mut goal = G1::zero_point(); + let mut goal = SomeCurve::zero_point(); // Naive multiply + add method. for (g, e) in gs.iter().zip(es.iter()) { goal = goal.plus_point(&g.mul_by_scalar(e)) diff --git a/rust-src/concordium_base/src/curve_arithmetic/secret_value.rs b/rust-src/concordium_base/src/curve_arithmetic/secret_value.rs index 60d38b1f5..3cf6612b6 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/secret_value.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/secret_value.rs @@ -99,8 +99,11 @@ impl Value { #[cfg(test)] mod tests { + use ark_bls12_381::{G1Projective, G2Projective}; + + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::{G1Affine, G2Affine}; macro_rules! macro_test_value_to_byte_conversion { ($function_name:ident, $curve_type:path) => { #[test] @@ -117,7 +120,17 @@ mod tests { }; } - macro_test_value_to_byte_conversion!(value_to_byte_conversion_bls12_381_g1_affine, G1Affine); - - macro_test_value_to_byte_conversion!(value_to_byte_conversion_bls12_381_g2_affine, G2Affine); + // TODO: the code used to be diefined using the affine representation, but + // ArkWorks' BLS does not implement `CurveGroup` for the affine representation. + // Is it important that it's the affine representation? For now, the BLS + // projective representation will be used here. + macro_test_value_to_byte_conversion!( + value_to_byte_conversion_bls12_381_g1_affine, + ArkGroup + ); + + macro_test_value_to_byte_conversion!( + value_to_byte_conversion_bls12_381_g2_affine, + ArkGroup + ); } diff --git a/rust-src/concordium_base/src/dodis_yampolskiy_prf/secret.rs b/rust-src/concordium_base/src/dodis_yampolskiy_prf/secret.rs index ed51efe9d..9cb4a366c 100644 --- a/rust-src/concordium_base/src/dodis_yampolskiy_prf/secret.rs +++ b/rust-src/concordium_base/src/dodis_yampolskiy_prf/secret.rs @@ -76,12 +76,16 @@ impl SecretKey { #[cfg(test)] mod tests { use super::*; - use pairing::bls12_381::G1; + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use ark_bls12_381::G1Projective; + + type SomeCurve = ArkGroup; + #[test] pub fn key_to_byte_conversion() { let mut csprng = thread_rng(); for _ in 1..100 { - let sk = SecretKey::::generate(&mut csprng); + let sk = SecretKey::::generate(&mut csprng); let res_sk2 = serialize_deserialize(&sk); assert!(res_sk2.is_ok()); let sk2 = res_sk2.unwrap(); diff --git a/rust-src/concordium_base/src/elgamal/cipher.rs b/rust-src/concordium_base/src/elgamal/cipher.rs index 514a60725..c49c6fd7d 100644 --- a/rust-src/concordium_base/src/elgamal/cipher.rs +++ b/rust-src/concordium_base/src/elgamal/cipher.rs @@ -109,8 +109,10 @@ pub fn multicombine(ciphers: &[Cipher], scalars: &[C::Scalar]) -> C #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::{G1, G2}; + use ark_bls12_381::{G1Projective, G2Projective}; macro_rules! macro_test_cipher_to_byte_conversion { ($function_name:ident, $curve_type:path) => { @@ -127,6 +129,6 @@ mod tests { }; } - macro_test_cipher_to_byte_conversion!(key_to_cipher_conversion_g1, G1); - macro_test_cipher_to_byte_conversion!(key_to_cipher_conversion_g2, G2); + macro_test_cipher_to_byte_conversion!(key_to_cipher_conversion_g1, ArkGroup); + macro_test_cipher_to_byte_conversion!(key_to_cipher_conversion_g2, ArkGroup); } diff --git a/rust-src/concordium_base/src/elgamal/message.rs b/rust-src/concordium_base/src/elgamal/message.rs index 30cc7e2bd..ec0f29eea 100644 --- a/rust-src/concordium_base/src/elgamal/message.rs +++ b/rust-src/concordium_base/src/elgamal/message.rs @@ -25,8 +25,11 @@ impl Message { #[cfg(test)] mod tests { + use ark_bls12_381::{G1Projective, G2Projective}; + + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::{G1, G2}; fn test_message_serialization_helper() { let mut csprng = thread_rng(); @@ -39,7 +42,11 @@ mod tests { } #[test] - pub fn message_to_byte_conversion_g1() { test_message_serialization_helper::(); } + pub fn message_to_byte_conversion_g1() { + test_message_serialization_helper::>(); + } #[test] - pub fn message_to_byte_conversion_g2() { test_message_serialization_helper::(); } + pub fn message_to_byte_conversion_g2() { + test_message_serialization_helper::>(); + } } diff --git a/rust-src/concordium_base/src/elgamal/mod.rs b/rust-src/concordium_base/src/elgamal/mod.rs index 965943f04..b6fc727b1 100644 --- a/rust-src/concordium_base/src/elgamal/mod.rs +++ b/rust-src/concordium_base/src/elgamal/mod.rs @@ -207,8 +207,10 @@ pub fn decrypt_from_chunks_given_table( #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::{G1, G2}; + use ark_bls12_381::{G1Projective, G2Projective}; use rand::{rngs::ThreadRng, Rng}; // This is a generic helper function that tests encryption/decryption in chunks. @@ -231,10 +233,14 @@ mod tests { } #[test] - fn encrypt_decrypt_success_g1() { test_encrypt_decrypt_success_generic::() } + fn encrypt_decrypt_success_g1() { + test_encrypt_decrypt_success_generic::>() + } #[test] - fn encrypt_decrypt_success_g2() { test_encrypt_decrypt_success_generic::() } + fn encrypt_decrypt_success_g2() { + test_encrypt_decrypt_success_generic::>() + } // This is a generic helper function that tests encryption/decryption in chunks. // It is parameterized by a curve, and the intention is that concrete tests are @@ -259,12 +265,12 @@ mod tests { #[test] fn encrypt_decrypt_exponent_success_g1() { - test_encrypt_decrypt_exponent_success_generic::() + test_encrypt_decrypt_exponent_success_generic::>() } #[test] fn encrypt_decrypt_exponent_success_g2() { - test_encrypt_decrypt_exponent_success_generic::() + test_encrypt_decrypt_exponent_success_generic::>() } // This is a generic helper function that tests encryption/decryption in chunks. @@ -288,7 +294,7 @@ mod tests { } #[test] - fn chunking_test_g1() { test_chunking_generic::() } + fn chunking_test_g1() { test_chunking_generic::>() } // This is a generic helper function that tests encryption/decryption in chunks. // It is parameterized by a curve, and the intention is that concrete tests are @@ -317,5 +323,7 @@ mod tests { } #[test] - fn chunked_encrypt_decrypt_test_g1() { test_chunked_encrypt_decrypt_generic::() } + fn chunked_encrypt_decrypt_test_g1() { + test_chunked_encrypt_decrypt_generic::>() + } } diff --git a/rust-src/concordium_base/src/elgamal/public.rs b/rust-src/concordium_base/src/elgamal/public.rs index fe0e19514..7b5cf6e82 100644 --- a/rust-src/concordium_base/src/elgamal/public.rs +++ b/rust-src/concordium_base/src/elgamal/public.rs @@ -147,8 +147,11 @@ impl PublicKey { #[cfg(test)] mod tests { + use ark_bls12_381::{G1Projective, G2Projective}; + + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::{G1, G2}; macro_rules! macro_test_key_to_byte_conversion { ($function_name:ident, $curve_type:path) => { @@ -167,6 +170,6 @@ mod tests { }; } - macro_test_key_to_byte_conversion!(key_to_byte_conversion_g1, G1); - macro_test_key_to_byte_conversion!(key_to_byte_conversion_g2, G2); + macro_test_key_to_byte_conversion!(key_to_byte_conversion_g1, ArkGroup); + macro_test_key_to_byte_conversion!(key_to_byte_conversion_g2, ArkGroup); } diff --git a/rust-src/concordium_base/src/elgamal/secret.rs b/rust-src/concordium_base/src/elgamal/secret.rs index edb1c2ad2..fd4b1f4e8 100644 --- a/rust-src/concordium_base/src/elgamal/secret.rs +++ b/rust-src/concordium_base/src/elgamal/secret.rs @@ -167,8 +167,12 @@ impl SecretKey { #[cfg(test)] mod tests { + use ark_bls12_381::{G1Projective, G2Projective}; + + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::{G1, G2}; + macro_rules! macro_test_secret_key_to_byte_conversion { ($function_name:ident, $curve_type:path) => { #[test] @@ -185,8 +189,14 @@ mod tests { }; } - macro_test_secret_key_to_byte_conversion!(secret_key_to_byte_conversion_g1, G1); - macro_test_secret_key_to_byte_conversion!(secret_key_to_byte_conversion_g2, G2); + macro_test_secret_key_to_byte_conversion!( + secret_key_to_byte_conversion_g1, + ArkGroup + ); + macro_test_secret_key_to_byte_conversion!( + secret_key_to_byte_conversion_g2, + ArkGroup + ); // Test serialiation of baby-step-giant-step since it is implemented manually. #[test] @@ -194,7 +204,10 @@ mod tests { let mut csprng = thread_rng(); let m = 1 << 16; for _ in 0..10 { - let bsgs = BabyStepGiantStep::::new(&G1::generate(&mut csprng), m); + let bsgs = BabyStepGiantStep::>::new( + &>::generate(&mut csprng), + m, + ); let res = serialize_deserialize(&bsgs); assert!( res.is_ok(), diff --git a/rust-src/concordium_base/src/encrypted_transfers/ffi.rs b/rust-src/concordium_base/src/encrypted_transfers/ffi.rs index 9570ed1fe..bf22c9b28 100644 --- a/rust-src/concordium_base/src/encrypted_transfers/ffi.rs +++ b/rust-src/concordium_base/src/encrypted_transfers/ffi.rs @@ -3,11 +3,12 @@ //! scheduler, and the mobile wallet. use super::*; -use crate::{common::*, elgamal, ffi_helpers::*}; +use crate::{common::*, curve_arithmetic::arkworks_instances::ArkGroup, elgamal, ffi_helpers::*}; +use ark_bls12_381::G1Projective; use rand::prelude::StdRng; use std::io::Cursor; -type Group = pairing::bls12_381::G1; +type Group = ArkGroup; /// # Safety /// This function is safe if the pointers are all non-null, and produced diff --git a/rust-src/concordium_base/src/encrypted_transfers/mod.rs b/rust-src/concordium_base/src/encrypted_transfers/mod.rs index fc1f82eb1..43e10512e 100644 --- a/rust-src/concordium_base/src/encrypted_transfers/mod.rs +++ b/rust-src/concordium_base/src/encrypted_transfers/mod.rs @@ -279,14 +279,18 @@ pub fn verify_sec_to_pub_transfer_data( #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::G1; + use ark_bls12_381::G1Projective; + + type SomeCurve = ArkGroup; // Test that decryption is the inverse to encryption. #[test] fn test_encrypt_decrypt() { let mut csprng = thread_rng(); - let context = GlobalContext::::generate(String::from("genesis_string")); + let context = GlobalContext::::generate(String::from("genesis_string")); let sk = SecretKey::generate(context.elgamal_generator(), &mut csprng); let pk = PublicKey::from(&sk); @@ -308,7 +312,7 @@ mod tests { #[test] fn test_scale() { let mut csprng = thread_rng(); - let context = GlobalContext::::generate(String::from("genesis_string")); + let context = GlobalContext::::generate(String::from("genesis_string")); let sk = SecretKey::generate(context.elgamal_generator(), &mut csprng); let pk = PublicKey::from(&sk); @@ -334,7 +338,7 @@ mod tests { #[test] fn test_encryption_randomness_zero() { let mut csprng = thread_rng(); - let context = GlobalContext::::generate(String::from("genesis_string")); + let context = GlobalContext::::generate(String::from("genesis_string")); let sk = SecretKey::generate(context.elgamal_generator(), &mut csprng); let amount = Amount::from_micro_ccd(csprng.gen::()); let dummy_encryption = encrypt_amount_with_fixed_randomness(&context, amount); @@ -352,9 +356,10 @@ mod tests { #[test] fn test_make_and_verify_transfer_data() { let mut csprng = thread_rng(); - let sk_sender: SecretKey = SecretKey::generate_all(&mut csprng); + let sk_sender: SecretKey = SecretKey::generate_all(&mut csprng); let pk_sender = PublicKey::from(&sk_sender); - let sk_receiver: SecretKey = SecretKey::generate(&pk_sender.generator, &mut csprng); + let sk_receiver: SecretKey = + SecretKey::generate(&pk_sender.generator, &mut csprng); let pk_receiver = PublicKey::from(&sk_receiver); let s: u64 = csprng.gen(); // amount on account. @@ -364,7 +369,7 @@ mod tests { let n = 32; let nm = n * m; - let context = GlobalContext::::generate_size(String::from("genesis_string"), nm); + let context = GlobalContext::::generate_size(String::from("genesis_string"), nm); let S_in_chunks = encrypt_amount(&context, &pk_sender, Amount::from_micro_ccd(s), &mut csprng); @@ -400,7 +405,7 @@ mod tests { #[allow(non_snake_case)] fn test_make_and_verify_sec_to_pub_transfer_data() { let mut csprng = thread_rng(); - let sk_sender: SecretKey = SecretKey::generate_all(&mut csprng); + let sk_sender: SecretKey = SecretKey::generate_all(&mut csprng); let pk_sender = PublicKey::from(&sk_sender); let s: u64 = csprng.gen(); // amount on account. @@ -410,7 +415,7 @@ mod tests { let n = 32; let nm = n * m; - let context = GlobalContext::::generate_size(String::from("genesis_string"), nm); + let context = GlobalContext::::generate_size(String::from("genesis_string"), nm); let S_in_chunks = encrypt_amount(&context, &pk_sender, Amount::from_micro_ccd(s), &mut csprng); diff --git a/rust-src/concordium_base/src/encrypted_transfers/proofs/generate_proofs.rs b/rust-src/concordium_base/src/encrypted_transfers/proofs/generate_proofs.rs index 903fbd128..283702569 100644 --- a/rust-src/concordium_base/src/encrypted_transfers/proofs/generate_proofs.rs +++ b/rust-src/concordium_base/src/encrypted_transfers/proofs/generate_proofs.rs @@ -655,11 +655,14 @@ pub fn verify_sec_to_pub_trans( #[cfg(test)] mod test { + use ark_bls12_381::G1Projective; + + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::G1; - // use rand::{rngs::ThreadRng, Rng}; - type SomeCurve = G1; + type SomeCurve = ArkGroup; + // Copied from common.rs in sigma_protocols since apparently it is not available pub fn generate_challenge_prefix(csprng: &mut R) -> Vec { // length of the challenge @@ -675,9 +678,10 @@ mod test { #[test] fn test_enc_trans() { let mut csprng = thread_rng(); - let sk_sender: SecretKey = SecretKey::generate_all(&mut csprng); + let sk_sender: SecretKey = SecretKey::generate_all(&mut csprng); let pk_sender = PublicKey::from(&sk_sender); - let sk_receiver: SecretKey = SecretKey::generate(&pk_sender.generator, &mut csprng); + let sk_receiver: SecretKey = + SecretKey::generate(&pk_sender.generator, &mut csprng); let pk_receiver = PublicKey::from(&sk_receiver); let s = csprng.gen::(); // amount on account. @@ -727,7 +731,7 @@ mod test { #[test] fn test_sec_to_pub() { let mut csprng = thread_rng(); - let sk: SecretKey = SecretKey::generate_all(&mut csprng); + let sk: SecretKey = SecretKey::generate_all(&mut csprng); let pk = PublicKey::from(&sk); let s = csprng.gen::(); // amount on account. diff --git a/rust-src/concordium_base/src/id/account_holder.rs b/rust-src/concordium_base/src/id/account_holder.rs index 358a8d48d..c799fe8f3 100644 --- a/rust-src/concordium_base/src/id/account_holder.rs +++ b/rust-src/concordium_base/src/id/account_holder.rs @@ -1260,13 +1260,18 @@ mod tests { use crate::{ common::types::{KeyIndex, KeyPair}, - curve_arithmetic::Curve, + curve_arithmetic::{ + arkworks_instances::{ArkField, ArkGroup}, + Curve, + }, id::{constants::*, identity_provider::*, secret_sharing::Threshold, test::*}, pedersen_commitment::CommitmentKey as PedersenKey, }; + use ark_bls12_381::{g1, Fr, G1Projective}; + use ark_ec::short_weierstrass::Projective; use either::Either::Left; - type ExampleCurve = pairing::bls12_381::G1; + type ExampleCurve = ArkGroup>; // ArkGroup; const EXPIRY: TransactionTime = TransactionTime { seconds: 111111111111111111, @@ -1353,7 +1358,8 @@ mod tests { let num_ars = 4; let threshold = 3; let ar_base = ExampleCurve::generate(&mut csprng); - let (ars_infos, _ar_keys) = test_create_ars(&ar_base, num_ars, &mut csprng); + let ars = test_create_ars(&ar_base, num_ars, &mut csprng); + let ars_infos: BTreeMap> = ars.0; let ck = PedersenKey::generate(&mut csprng); let value = Value::::generate(&mut csprng); @@ -1416,8 +1422,9 @@ mod tests { num_ars, &acc_data, ); - let alist = test_create_attributes(); - let ver_ok = verify_credentials( + let alist: AttributeList<::ScalarField, AttributeKind> = + test_create_attributes(); + let ver_ok = verify_credentials::( &pio, context, &alist, diff --git a/rust-src/concordium_base/src/id/chain.rs b/rust-src/concordium_base/src/id/chain.rs index 6007621ef..758aa9a01 100644 --- a/rust-src/concordium_base/src/id/chain.rs +++ b/rust-src/concordium_base/src/id/chain.rs @@ -354,13 +354,16 @@ mod tests { use crate::{ common::types::{KeyIndex, KeyPair}, + curve_arithmetic::arkworks_instances::ArkGroup, id::{account_holder::*, constants::*, identity_provider::*, test::*}, }; - use pairing::bls12_381::G1; + use ark_bls12_381::G1Projective; use rand::*; use std::collections::btree_map::BTreeMap; use Either::{Left, Right}; + type SomeCurve = ArkGroup; + const EXPIRY: TransactionTime = TransactionTime { seconds: 111111111111111111, }; @@ -377,7 +380,7 @@ mod tests { ip_secret_key, ip_cdi_secret_key, } = test_create_ip_info(&mut csprng, num_ars, max_attrs); - let global_ctx = GlobalContext::::generate(String::from("genesis_string")); + let global_ctx = GlobalContext::::generate(String::from("genesis_string")); let (ars_infos, _) = test_create_ars(&global_ctx.on_chain_commitment_key.g, num_ars, &mut csprng); let id_use_data = test_create_id_use_data(&mut csprng); @@ -501,7 +504,7 @@ mod tests { ip_secret_key, .. // ip_cdi_secret_key is not used since we are testing the flow without initial account creation } = test_create_ip_info(&mut csprng, num_ars, max_attrs); - let global_ctx = GlobalContext::::generate(String::from("genesis_string")); + let global_ctx = GlobalContext::::generate(String::from("genesis_string")); let (ars_infos, _) = test_create_ars(&global_ctx.on_chain_commitment_key.g, num_ars, &mut csprng); let id_use_data = test_create_id_use_data(&mut csprng); @@ -601,7 +604,7 @@ mod tests { ip_secret_key, ip_cdi_secret_key, } = test_create_ip_info(&mut csprng, num_ars, max_attrs); - let global_ctx = GlobalContext::::generate(String::from("genesis_string")); + let global_ctx = GlobalContext::::generate(String::from("genesis_string")); let (ars_infos, _) = test_create_ars(&global_ctx.on_chain_commitment_key.g, num_ars, &mut csprng); let id_use_data = test_create_id_use_data(&mut csprng); diff --git a/rust-src/concordium_base/src/id/constants.rs b/rust-src/concordium_base/src/id/constants.rs index 8a8bae5ce..aaeee1eda 100644 --- a/rust-src/concordium_base/src/id/constants.rs +++ b/rust-src/concordium_base/src/id/constants.rs @@ -6,10 +6,14 @@ use crate::{ Buffer, Deserial, Get, ParseResult, Put, ReadBytesExt, SerdeDeserialize, SerdeSerialize, Serial, }, - curve_arithmetic::{Curve, Pairing}, + curve_arithmetic::{ + arkworks_instances::{ArkField, ArkGroup}, + Curve, Pairing, + }, }; use anyhow::bail; -use pairing::bls12_381::G1; +use ark_bls12_381::{g1, G1Projective}; +use ark_ec::{bls12::Bls12, short_weierstrass::Projective}; use serde::{ de::{self, Visitor}, Deserializer, Serializer, @@ -18,12 +22,13 @@ use std::{fmt, io::Cursor, str::FromStr}; use thiserror::Error; /// Curve used by the anonymity revoker. -pub type ArCurve = pairing::bls12_381::G1; +pub type ArCurve = ArkGroup>; /// Pairing used by the identity provider. -pub type IpPairing = pairing::bls12_381::Bls12; +pub type IpPairing = Bls12; /// Field used by the identity provider and anonymity revoker. -/// This isthe base field of both the ArCurve and the IpPairing. -pub type BaseField = ::ScalarField; +/// This is the base field of both the ArCurve and the IpPairing. +pub type BaseField = ::ScalarField; +// pub type BaseField = ArkField; /// Index used to create the RegId of the initial credential. pub const INITIAL_CREDENTIAL_INDEX: u8 = 0; @@ -110,13 +115,13 @@ impl From for AttributeKind { fn from(x: u64) -> Self { AttributeKind(x.to_string()) } } -impl Attribute<::Scalar> for AttributeKind { - fn to_field_element(&self) -> ::Scalar { +impl Attribute< as Curve>::Scalar> for AttributeKind { + fn to_field_element(&self) -> as Curve>::Scalar { let mut buf = [0u8; 32]; let len = self.0.as_bytes().len(); buf[1 + (31 - len)..].copy_from_slice(self.0.as_bytes()); buf[0] = len as u8; // this should be valid because len <= 31 so the first two bits will be unset - <::Scalar as Deserial>::deserial(&mut Cursor::new(&buf)) + < as Curve>::Scalar as Deserial>::deserial(&mut Cursor::new(&buf)) .expect("31 bytes + length fits into a scalar.") } } diff --git a/rust-src/concordium_base/src/id/ffi.rs b/rust-src/concordium_base/src/id/ffi.rs index 8e86830a0..72c0e8284 100644 --- a/rust-src/concordium_base/src/id/ffi.rs +++ b/rust-src/concordium_base/src/id/ffi.rs @@ -8,12 +8,13 @@ use super::{ use crate::{ bulletproofs::utils::Generators, common::{size_t, types::TransactionTime, *}, + curve_arithmetic::arkworks_instances::ArkGroup, ffi_helpers::*, pedersen_commitment::CommitmentKey as PedersenKey, }; use anyhow::Context; +use ark_bls12_381::G1Projective; use either::Either::{Left, Right}; -use pairing::bls12_381::{Bls12, G1}; use rand::thread_rng; use std::{ collections::BTreeMap, @@ -22,6 +23,9 @@ use std::{ str::from_utf8, }; +type Bls12 = ark_ec::bls12::Bls12; +type G1 = ArkGroup; + #[no_mangle] #[allow(clippy::not_unsafe_ptr_arg_deref)] extern "C" fn verify_initial_cdi_ffi( diff --git a/rust-src/concordium_base/src/id/id_proof_types.rs b/rust-src/concordium_base/src/id/id_proof_types.rs index 85318f498..1f05a2033 100644 --- a/rust-src/concordium_base/src/id/id_proof_types.rs +++ b/rust-src/concordium_base/src/id/id_proof_types.rs @@ -12,13 +12,15 @@ use crate::{ set_non_membership_proof::SetNonMembershipProof, }, common::*, - curve_arithmetic::Curve, + curve_arithmetic::{arkworks_instances::ArkGroup, Curve}, sigma_protocols::dlog::Response as DlogResponse, }; -use pairing::bls12_381::G1; +use ark_bls12_381::G1Projective; use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize}; use std::{collections::BTreeSet, convert::TryFrom, marker::PhantomData, str::FromStr}; +type G1 = ArkGroup; + #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy)] pub enum ProofVersion { Version1, diff --git a/rust-src/concordium_base/src/id/id_verifier.rs b/rust-src/concordium_base/src/id/id_verifier.rs index 9114a9e86..7ee789368 100644 --- a/rust-src/concordium_base/src/id/id_verifier.rs +++ b/rust-src/concordium_base/src/id/id_verifier.rs @@ -328,9 +328,10 @@ mod tests { use super::*; use crate::{ common::types::{KeyIndex, KeyPair}, + curve_arithmetic::arkworks_instances::ArkGroup, id::{constants::AttributeKind, id_prover::*}, }; - use pairing::bls12_381::G1; + use ark_bls12_381::G1Projective; use rand::*; use std::{ collections::{btree_map::BTreeMap, BTreeSet}, @@ -338,6 +339,8 @@ mod tests { marker::PhantomData, }; + type G1 = ArkGroup; + #[test] fn test_verify_account_ownership() { let mut csprng = thread_rng(); diff --git a/rust-src/concordium_base/src/id/identity_provider.rs b/rust-src/concordium_base/src/id/identity_provider.rs index e0b7fdfa8..f64342980 100644 --- a/rust-src/concordium_base/src/id/identity_provider.rs +++ b/rust-src/concordium_base/src/id/identity_provider.rs @@ -685,7 +685,6 @@ mod tests { id::{account_holder::generate_id_recovery_request, constants::ArCurve, test::*}, pedersen_commitment::{CommitmentKey, Value as PedersenValue}, }; - use ff::Field; use std::collections::btree_map::BTreeMap; const EXPIRY: TransactionTime = TransactionTime { diff --git a/rust-src/concordium_base/src/id/secret_sharing.rs b/rust-src/concordium_base/src/id/secret_sharing.rs index 6188a5ca1..3b92a4986 100644 --- a/rust-src/concordium_base/src/id/secret_sharing.rs +++ b/rust-src/concordium_base/src/id/secret_sharing.rs @@ -197,10 +197,14 @@ pub fn reveal_in_group + Copy, C: Curve>(shares: &[(P, C)]) -> C { #[cfg(test)] mod test { + use crate::curve_arithmetic::arkworks_instances::{ArkField, ArkGroup}; + use super::*; - use pairing::bls12_381::{Fr, G1}; + use ark_bls12_381::{Fr, G1Projective}; use rand::seq::SliceRandom; + type G1 = ArkGroup; + // Test Lagrange interpolation polynomials at x={0,1} #[test] pub fn test_lagrange() { @@ -278,7 +282,7 @@ mod test { .iter() .map(|(n, s)| (*n, generator.mul_by_scalar(s))) .collect::>(); - let revealed_data: Fr = reveal::<_, G1>(sufficient_sample); + let revealed_data: ArkField = reveal::<_, G1>(sufficient_sample); assert_eq!(revealed_data, secret); let revealed_data_point: G1 = reveal_in_group::<_, G1>(&sufficient_sample_points); assert_eq!(revealed_data_point, secret_point); @@ -300,7 +304,7 @@ mod test { let rand_elm = shares.choose_mut(&mut csprng).unwrap(); rand_elm.1 = crate::curve_arithmetic::Value::generate(&mut csprng); - let revealed_data: Fr = reveal::<_, G1>(&shares); + let revealed_data: ArkField = reveal::<_, G1>(&shares); assert_ne!(revealed_data, secret); let sufficient_points_err = shares .iter() @@ -327,7 +331,7 @@ mod test { .iter() .map(|(n, s)| (*n, generator.mul_by_scalar(s))) .collect::>(); - let revealed_data: Fr = reveal::<_, G1>(insufficient_sample); + let revealed_data: ArkField = reveal::<_, G1>(insufficient_sample); assert_ne!(revealed_data, secret); let revealed_data_point: G1 = reveal_in_group::<_, G1>(&insufficient_sample_points); assert_ne!(revealed_data_point, secret_point); diff --git a/rust-src/concordium_base/src/id/test.rs b/rust-src/concordium_base/src/id/test.rs index 6d4e22570..d549cedff 100644 --- a/rust-src/concordium_base/src/id/test.rs +++ b/rust-src/concordium_base/src/id/test.rs @@ -60,7 +60,7 @@ pub fn test_create_ars( } /// Create identity provider with #num_ars ARs to be used by tests -pub fn test_create_ip_info( +pub fn test_create_ip_info( csprng: &mut T, num_ars: u8, max_attrs: u8, diff --git a/rust-src/concordium_base/src/id/utils.rs b/rust-src/concordium_base/src/id/utils.rs index a541f219c..4f1239bb4 100644 --- a/rust-src/concordium_base/src/id/utils.rs +++ b/rust-src/concordium_base/src/id/utils.rs @@ -324,15 +324,15 @@ where #[cfg(test)] mod tests { use super::*; - use crate::common::to_bytes; - use pairing::bls12_381::Fr; + use crate::{common::to_bytes, curve_arithmetic::arkworks_instances::ArkField}; + use ark_bls12_381::Fr; use rand::{thread_rng, Rng}; use std::collections::BTreeMap; #[test] pub fn test_last_bit() { let ars = (1..10).map(ArIdentity::new).collect::>(); - let encoded = encode_ars::(&ars).expect("Encodign should succeed."); + let encoded = encode_ars::>(&ars).expect("Encodign should succeed."); // Field size of Fr is 254 bits, so what we expect is to have two scalars assert_eq!(encoded.len(), 2, "Encoded ARs should fit into two scalars."); let s1 = to_bytes(&encoded[0]); @@ -357,7 +357,7 @@ mod tests { *x = ArIdentity::new(csprng.gen_range(1, 100)); } let set = xs.iter().copied().collect::>(); - let encoded = encode_ars::(&set).expect("Encoding should succeed."); + let encoded = encode_ars::>(&set).expect("Encoding should succeed."); if let Some(set_ex) = seen.insert(encoded.clone(), set.clone()) { assert_eq!(set, set_ex); } diff --git a/rust-src/concordium_base/src/pedersen_commitment/commitment.rs b/rust-src/concordium_base/src/pedersen_commitment/commitment.rs index a2ecfde5c..ebb24024f 100644 --- a/rust-src/concordium_base/src/pedersen_commitment/commitment.rs +++ b/rust-src/concordium_base/src/pedersen_commitment/commitment.rs @@ -40,9 +40,14 @@ impl std::borrow::Borrow for Commitment { #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::{G1, G2}; + use ark_bls12_381::{G1Projective, G2Projective}; use rand::*; + type G1 = ArkGroup; + type G2 = ArkGroup; + impl Commitment { pub fn generate(csprng: &mut T) -> Commitment { Commitment(C::generate(csprng)) } } diff --git a/rust-src/concordium_base/src/pedersen_commitment/key.rs b/rust-src/concordium_base/src/pedersen_commitment/key.rs index c74f66fb7..cd2222123 100644 --- a/rust-src/concordium_base/src/pedersen_commitment/key.rs +++ b/rust-src/concordium_base/src/pedersen_commitment/key.rs @@ -147,8 +147,12 @@ impl VecCommitmentKey { #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::{G1Affine, G2Affine, G1, G2}; + use ark_bls12_381::{G1Projective, G2Projective}; + type G1 = ArkGroup; + type G2 = ArkGroup; macro_rules! macro_test_key_byte_conversion { ($function_name:ident, $curve_type:path) => { @@ -166,9 +170,11 @@ mod tests { }; } - macro_test_key_byte_conversion!(key_byte_conversion_bls12_381_g1_affine, G1Affine); + // NOTE: ArkWorks doesn't provide `CurveGroup` instances for the affine + // representation + macro_test_key_byte_conversion!(key_byte_conversion_bls12_381_g1_projective, G1); - macro_test_key_byte_conversion!(key_byte_conversion_bls12_381_g2_affine, G2Affine); + macro_test_key_byte_conversion!(key_byte_conversion_bls12_381_g2_projective, G2); macro_rules! macro_test_commit_open { ($function_name:ident, $curve_type:path) => { @@ -217,15 +223,15 @@ mod tests { }; } - macro_test_commit_open!(commit_open_bls12_381_g1_affine, G1Affine); + // macro_test_commit_open!(commit_open_bls12_381_g1_affine, G1Affine); macro_test_commit_open!(commit_open_bls12_381_g1_projectitve, G1); - macro_test_commit_open!(commit_open_bls12_381_g2_affine, G2Affine); + // macro_test_commit_open!(commit_open_bls12_381_g2_affine, G2Affine); macro_test_commit_open!(commit_open_bls12_381_g2_projective, G2); - macro_test_commit_open_vec!(vec_commit_open_bls12_381_g1_affine, G1Affine); + // macro_test_commit_open_vec!(vec_commit_open_bls12_381_g1_affine, G1Affine); macro_test_commit_open_vec!(vec_commit_open_bls12_381_g1_projective, G1); - macro_test_commit_open_vec!(vec_commit_open_bls12_381_g2_affine, G2Affine); + // macro_test_commit_open_vec!(vec_commit_open_bls12_381_g2_affine, G2Affine); macro_test_commit_open_vec!(vec_commit_open_bls12_381_g2_projective, G2); } diff --git a/rust-src/concordium_base/src/pedersen_commitment/randomness.rs b/rust-src/concordium_base/src/pedersen_commitment/randomness.rs index dae67094e..8d7afa55b 100644 --- a/rust-src/concordium_base/src/pedersen_commitment/randomness.rs +++ b/rust-src/concordium_base/src/pedersen_commitment/randomness.rs @@ -79,8 +79,12 @@ impl Randomness { #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::{G1Affine, G2Affine}; + use ark_bls12_381::{G1Projective, G2Projective}; + type G1 = ArkGroup; + type G2 = ArkGroup; macro_rules! macro_test_randomness_to_byte_conversion { ($function_name:ident, $curve_type:path) => { #[test] @@ -97,13 +101,16 @@ mod tests { }; } + // NOTE: ArkWorks doesn't provide `CurveGroup` instances for the affine + // representation + macro_test_randomness_to_byte_conversion!( - randomness_to_byte_conversion_bls12_381_g1_affine, - G1Affine + randomness_to_byte_conversion_bls12_381_g1_projective, + G1 ); macro_test_randomness_to_byte_conversion!( - randomness_to_byte_conversion_bls12_381_g2_affine, - G2Affine + randomness_to_byte_conversion_bls12_381_g2_projective, + G2 ); } diff --git a/rust-src/concordium_base/src/ps_sig/known_message.rs b/rust-src/concordium_base/src/ps_sig/known_message.rs index 17bc245d1..aadfeb4d8 100644 --- a/rust-src/concordium_base/src/ps_sig/known_message.rs +++ b/rust-src/concordium_base/src/ps_sig/known_message.rs @@ -33,7 +33,8 @@ impl KnownMessage { #[cfg(test)] mod tests { use super::*; - use pairing::bls12_381::Bls12; + + type Bls12 = ark_ec::models::bls12::Bls12; macro_rules! macro_test_message_to_byte_conversion { ($function_name:ident, $pairing_type:path) => { diff --git a/rust-src/concordium_base/src/ps_sig/public.rs b/rust-src/concordium_base/src/ps_sig/public.rs index ba798ce95..4789966e3 100644 --- a/rust-src/concordium_base/src/ps_sig/public.rs +++ b/rust-src/concordium_base/src/ps_sig/public.rs @@ -103,7 +103,7 @@ impl From<&SecretKey> for PublicKey { #[cfg(test)] mod tests { use super::*; - use pairing::bls12_381::Bls12; + type Bls12 = ark_ec::models::bls12::Bls12; macro_rules! macro_test_public_key_to_byte_conversion { ($function_name:ident, $pairing_type:path) => { diff --git a/rust-src/concordium_base/src/ps_sig/secret.rs b/rust-src/concordium_base/src/ps_sig/secret.rs index 17a07d9a5..2268b06bd 100644 --- a/rust-src/concordium_base/src/ps_sig/secret.rs +++ b/rust-src/concordium_base/src/ps_sig/secret.rs @@ -99,7 +99,7 @@ impl SecretKey { #[cfg(test)] mod tests { use super::*; - use pairing::bls12_381::Bls12; + type Bls12 = ark_ec::models::bls12::Bls12; macro_rules! macro_test_secret_key_to_byte_conversion { ($function_name:ident, $pairing_type:path) => { diff --git a/rust-src/concordium_base/src/ps_sig/signature.rs b/rust-src/concordium_base/src/ps_sig/signature.rs index 5d11a5023..08d1a4c83 100644 --- a/rust-src/concordium_base/src/ps_sig/signature.rs +++ b/rust-src/concordium_base/src/ps_sig/signature.rs @@ -65,7 +65,7 @@ impl Signature { #[cfg(test)] mod tests { use super::*; - use pairing::bls12_381::Bls12; + type Bls12 = ark_ec::models::bls12::Bls12; macro_rules! macro_test_signature_to_byte_conversion { ($function_name:ident, $pairing_type:path) => { diff --git a/rust-src/concordium_base/src/ps_sig/unknown_message.rs b/rust-src/concordium_base/src/ps_sig/unknown_message.rs index eb465e7af..ac4b7567e 100644 --- a/rust-src/concordium_base/src/ps_sig/unknown_message.rs +++ b/rust-src/concordium_base/src/ps_sig/unknown_message.rs @@ -75,7 +75,7 @@ impl UnknownMessage { #[cfg(test)] mod tests { use super::*; - use pairing::bls12_381::Bls12; + type Bls12 = ark_ec::models::bls12::Bls12; macro_rules! macro_test_unknown_message_to_byte_conversion { ($function_name:ident, $pairing_type:path) => { diff --git a/rust-src/concordium_base/src/sigma_protocols/aggregate_dlog.rs b/rust-src/concordium_base/src/sigma_protocols/aggregate_dlog.rs index 6890df4ed..1b75af1e7 100644 --- a/rust-src/concordium_base/src/sigma_protocols/aggregate_dlog.rs +++ b/rust-src/concordium_base/src/sigma_protocols/aggregate_dlog.rs @@ -119,10 +119,14 @@ impl SigmaProtocol for AggregateDlog { #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::G1; + use ark_bls12_381::G1Projective; use rand::{thread_rng, Rng}; + type G1 = ArkGroup; + #[test] pub fn test_aggregate_dlog_correctness() { let mut csprng = thread_rng(); diff --git a/rust-src/concordium_base/src/sigma_protocols/com_enc_eq.rs b/rust-src/concordium_base/src/sigma_protocols/com_enc_eq.rs index 920c42d46..59e8bf7d3 100644 --- a/rust-src/concordium_base/src/sigma_protocols/com_enc_eq.rs +++ b/rust-src/concordium_base/src/sigma_protocols/com_enc_eq.rs @@ -200,9 +200,13 @@ impl SigmaProtocol for ComEncEq { #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; use crate::elgamal::{Message, SecretKey as ElgamalSecretKey}; - use pairing::bls12_381::G1; + use ark_bls12_381::G1Projective; + + type G1 = ArkGroup; #[test] pub fn test_com_enc_eq_correctness() { diff --git a/rust-src/concordium_base/src/sigma_protocols/com_eq.rs b/rust-src/concordium_base/src/sigma_protocols/com_eq.rs index 95c9b82e6..1a555c9eb 100644 --- a/rust-src/concordium_base/src/sigma_protocols/com_eq.rs +++ b/rust-src/concordium_base/src/sigma_protocols/com_eq.rs @@ -153,8 +153,13 @@ impl> SigmaProtocol for ComEq { #[cfg(test)] mod test { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::{G1, G2}; + use ark_bls12_381::{G1Projective, G2Projective}; + + type G1 = ArkGroup; + type G2 = ArkGroup; #[test] pub fn test_com_eq_correctness() { diff --git a/rust-src/concordium_base/src/sigma_protocols/com_eq_different_groups.rs b/rust-src/concordium_base/src/sigma_protocols/com_eq_different_groups.rs index 960a40bfd..1a7af388e 100644 --- a/rust-src/concordium_base/src/sigma_protocols/com_eq_different_groups.rs +++ b/rust-src/concordium_base/src/sigma_protocols/com_eq_different_groups.rs @@ -163,8 +163,13 @@ impl> SigmaProtocol for ComEqDiffGroup #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::{G1, G2}; + use ark_bls12_381::{G1Projective, G2Projective}; + + type G1 = ArkGroup; + type G2 = ArkGroup; #[test] pub fn test_com_eq_diff_grps_correctness() { diff --git a/rust-src/concordium_base/src/sigma_protocols/com_eq_sig.rs b/rust-src/concordium_base/src/sigma_protocols/com_eq_sig.rs index ddd414619..c472c5d1e 100644 --- a/rust-src/concordium_base/src/sigma_protocols/com_eq_sig.rs +++ b/rust-src/concordium_base/src/sigma_protocols/com_eq_sig.rs @@ -292,9 +292,17 @@ impl> SigmaProtocol for ComEqSig

; + type Bls12 = ark_ec::models::bls12::Bls12; #[test] #[allow(non_snake_case)] diff --git a/rust-src/concordium_base/src/sigma_protocols/com_ineq.rs b/rust-src/concordium_base/src/sigma_protocols/com_ineq.rs index 12a92895c..ef9d689f5 100644 --- a/rust-src/concordium_base/src/sigma_protocols/com_ineq.rs +++ b/rust-src/concordium_base/src/sigma_protocols/com_ineq.rs @@ -131,9 +131,14 @@ pub fn verify_com_ineq( #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::{ArkField, ArkGroup}; + use super::*; - use ff::PrimeField; - use pairing::bls12_381::{Fr, G1}; + use ark_bls12_381::G1Projective; + use std::str::FromStr; + + type G1 = ArkGroup; + type Fr = ArkField; #[test] fn test_com_ineq_correctness() { diff --git a/rust-src/concordium_base/src/sigma_protocols/com_lin.rs b/rust-src/concordium_base/src/sigma_protocols/com_lin.rs index 217d2f5bc..93b71612c 100644 --- a/rust-src/concordium_base/src/sigma_protocols/com_lin.rs +++ b/rust-src/concordium_base/src/sigma_protocols/com_lin.rs @@ -217,12 +217,16 @@ impl SigmaProtocol for ComLin { #[allow(non_snake_case)] #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::{ArkField, ArkGroup}; + use super::*; - use ff::PrimeField; - use pairing::bls12_381::{Fr, G1}; - // use pairing::bls12_381::G1; + use crate::curve_arithmetic::PrimeField; + use ark_bls12_381::G1Projective; use rand::thread_rng; - // use std::convert::TryInto; + use std::str::FromStr; + + type G1 = ArkGroup; + type Fr = ArkField; #[test] pub fn test_com_lin_correctness() { diff --git a/rust-src/concordium_base/src/sigma_protocols/com_mult.rs b/rust-src/concordium_base/src/sigma_protocols/com_mult.rs index 538a6c4e8..ac375247c 100644 --- a/rust-src/concordium_base/src/sigma_protocols/com_mult.rs +++ b/rust-src/concordium_base/src/sigma_protocols/com_mult.rs @@ -172,10 +172,14 @@ impl SigmaProtocol for ComMult { #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::G1; + use ark_bls12_381::G1Projective; use rand::thread_rng; + type G1 = ArkGroup; + #[test] pub fn test_com_mult_correctness() { let mut csprng = thread_rng(); diff --git a/rust-src/concordium_base/src/sigma_protocols/dlog.rs b/rust-src/concordium_base/src/sigma_protocols/dlog.rs index 5d8949bc9..f6ac0a1ae 100644 --- a/rust-src/concordium_base/src/sigma_protocols/dlog.rs +++ b/rust-src/concordium_base/src/sigma_protocols/dlog.rs @@ -100,8 +100,12 @@ impl SigmaProtocol for Dlog { #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::G1; + use ark_bls12_381::G1Projective; + + type G1 = ArkGroup; #[test] pub fn test_dlog_correctness() { diff --git a/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs b/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs index ede9fc3d0..65a04e97d 100644 --- a/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs +++ b/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs @@ -147,11 +147,18 @@ impl SigmaProtocol for DlogAndAggregateDlogsEqual { #[cfg(test)] mod test { use super::*; - use crate::curve_arithmetic::multiexp; - use ff::PrimeField; - use pairing::bls12_381::{Fr, G1}; + use crate::curve_arithmetic::{ + arkworks_instances::{ArkField, ArkGroup}, + multiexp, + }; use rand::*; + use ark_bls12_381::G1Projective; + use std::str::FromStr; + + type G1 = ArkGroup; + type Fr = ArkField; + pub fn generate_challenge_prefix(csprng: &mut R) -> Vec { // length of the challenge let l = csprng.gen_range(0, 1000); diff --git a/rust-src/concordium_base/src/sigma_protocols/dlogeq.rs b/rust-src/concordium_base/src/sigma_protocols/dlogeq.rs index f5aff2517..9b1a568fd 100644 --- a/rust-src/concordium_base/src/sigma_protocols/dlogeq.rs +++ b/rust-src/concordium_base/src/sigma_protocols/dlogeq.rs @@ -78,11 +78,18 @@ impl SigmaProtocol for DlogEqual { #[cfg(test)] mod test { use super::*; - use crate::curve_arithmetic::Value; - use ff::PrimeField; - use pairing::bls12_381::{Fr, G1}; + use crate::curve_arithmetic::{ + arkworks_instances::{ArkField, ArkGroup}, + Value, + }; use rand::*; + use ark_bls12_381::G1Projective; + use std::str::FromStr; + + type G1 = ArkGroup; + type Fr = ArkField; + pub fn generate_challenge_prefix(csprng: &mut R) -> Vec { // length of the challenge let l = csprng.gen_range(0, 1000); diff --git a/rust-src/concordium_base/src/sigma_protocols/enc_trans.rs b/rust-src/concordium_base/src/sigma_protocols/enc_trans.rs index 5efc601e7..b84f70d0e 100644 --- a/rust-src/concordium_base/src/sigma_protocols/enc_trans.rs +++ b/rust-src/concordium_base/src/sigma_protocols/enc_trans.rs @@ -364,12 +364,15 @@ impl SigmaProtocol for EncTrans { mod tests { use super::*; use crate::{ + curve_arithmetic::arkworks_instances::ArkGroup, elgamal::{PublicKey, Randomness, SecretKey}, pedersen_commitment::{Commitment, CommitmentKey}, }; - use pairing::bls12_381::G1; + use ark_bls12_381::G1Projective; use rand::Rng; + type G1 = ArkGroup; + impl EncTrans { fn with_valid_data( rng: &mut R, diff --git a/rust-src/concordium_base/src/sigma_protocols/sigma_test.rs b/rust-src/concordium_base/src/sigma_protocols/sigma_test.rs index 211ad0981..97f1c1939 100644 --- a/rust-src/concordium_base/src/sigma_protocols/sigma_test.rs +++ b/rust-src/concordium_base/src/sigma_protocols/sigma_test.rs @@ -1,8 +1,13 @@ use crate::{ + curve_arithmetic::arkworks_instances::ArkGroup, random_oracle::RandomOracle, sigma_protocols::{com_enc_eq, com_eq_sig, common::*, dlog}, }; -use pairing::bls12_381::{Bls12, G1, G2}; +use ark_bls12_381::{G1Projective, G2Projective}; + +type G1 = ArkGroup; +type G2 = ArkGroup; +type Bls12 = ark_ec::models::bls12::Bls12; #[test] pub fn test_and() { diff --git a/rust-src/concordium_base/src/sigma_protocols/vcom_eq.rs b/rust-src/concordium_base/src/sigma_protocols/vcom_eq.rs index 6198c8640..f0a981fa8 100644 --- a/rust-src/concordium_base/src/sigma_protocols/vcom_eq.rs +++ b/rust-src/concordium_base/src/sigma_protocols/vcom_eq.rs @@ -220,10 +220,14 @@ impl SigmaProtocol for VecComEq { #[cfg(test)] mod tests { + use crate::curve_arithmetic::arkworks_instances::ArkGroup; + use super::*; - use pairing::bls12_381::G1; + use ark_bls12_381::G1Projective; use rand::{thread_rng, Rng}; + type G1 = ArkGroup; + #[test] pub fn test_vcom_eq_correctness() { let mut csprng = thread_rng(); From f2b6a472e2a386ffb072ad13b521be4f67c44950 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Tue, 12 Dec 2023 22:15:35 +0100 Subject: [PATCH 05/53] Update keygen/derivation and benches to use ArkWorks BLS --- identity-provider-service/src/bin/main.rs | 2 +- mobile_wallet/Cargo.lock | 1 + rust-bins/Cargo.lock | 1 + rust-src/Cargo.lock | 12 +----- rust-src/concordium_base/Cargo.toml | 6 +-- .../benches/aggr_dlog_commit_message.rs | 6 ++- .../benches/aggregate_signatures.rs | 3 +- .../concordium_base/benches/bulletproofs.rs | 12 +++--- .../benches/commitment_to_share.rs | 8 +++- .../benches/eddsa_benchmarks.rs | 27 +++++------- .../benches/elgamal_benchmarks.rs | 18 +++++--- .../benches/encrypted_transfers_benchmarks.rs | 18 ++++---- .../concordium_base/benches/hash_bench.rs | 6 ++- rust-src/concordium_base/benches/msm_bench.rs | 6 ++- .../concordium_base/benches/multiexp_bench.rs | 6 ++- .../benches/range_proof_bench.rs | 17 ++------ .../benches/range_proof_dalek_bench.rs | 6 +-- .../benches/serialization_benches.rs | 7 +++- .../benches/set_proof_bench.rs | 8 ++-- .../concordium_base/benches/verify_cdi.rs | 14 ++++--- .../concordium_base/src/aggregate_sig/mod.rs | 6 +-- rust-src/concordium_base/src/cis2_types.rs | 10 ++++- .../concordium_base/src/common/serialize.rs | 4 +- rust-src/concordium_base/src/common/types.rs | 6 +-- .../curve_arithmetic/arkworks_instances.rs | 28 +++++++++++-- .../curve_arithmetic/bls12_381_arkworks.rs | 13 ------ rust-src/concordium_base/src/ecvrf/mod.rs | 2 +- rust-src/concordium_base/src/ecvrf/proof.rs | 6 ++- rust-src/concordium_base/src/ecvrf/public.rs | 10 ++--- rust-src/concordium_base/src/ecvrf/secret.rs | 11 ++--- .../src/eddsa_ed25519/dlog_ed25519.rs | 2 +- rust-src/concordium_base/src/elgamal/mod.rs | 6 +-- .../src/encrypted_transfers/mod.rs | 4 +- .../proofs/generate_proofs.rs | 6 +-- rust-src/concordium_base/src/id/ffi.rs | 2 +- .../src/id/identity_provider.rs | 4 +- rust-src/concordium_base/src/id/test.rs | 9 ++-- rust-src/concordium_base/src/id/types.rs | 18 +++----- rust-src/concordium_base/src/lib.rs | 2 +- .../src/sigma_protocols/common.rs | 2 +- .../src/sigma_protocols/enc_trans.rs | 4 +- .../src/sigma_protocols/vcom_eq.rs | 4 +- rust-src/concordium_base/src/transactions.rs | 15 ++++--- rust-src/concordium_base/src/web3id/mod.rs | 40 ++++++++++-------- rust-src/ed25519_hd_key_derivation/src/lib.rs | 7 +++- rust-src/key_derivation/src/lib.rs | 41 +++++++++---------- rust-src/keygen_bls/Cargo.toml | 1 + rust-src/keygen_bls/src/lib.rs | 26 +++++++----- 48 files changed, 252 insertions(+), 221 deletions(-) diff --git a/identity-provider-service/src/bin/main.rs b/identity-provider-service/src/bin/main.rs index 2355c202c..ccf9e3f5e 100644 --- a/identity-provider-service/src/bin/main.rs +++ b/identity-provider-service/src/bin/main.rs @@ -15,7 +15,7 @@ use concordium_base::{ types::*, }, }; -use ed25519_dalek::{ExpandedSecretKey, PublicKey}; +//use ed25519_dalek::{ExpandedSecretKey, PublicKey}; use log::{error, info, warn}; use reqwest::Client; use serde_json::{from_str, json, to_value}; diff --git a/mobile_wallet/Cargo.lock b/mobile_wallet/Cargo.lock index 93b1cc5cd..ce08b3a2d 100644 --- a/mobile_wallet/Cargo.lock +++ b/mobile_wallet/Cargo.lock @@ -1043,6 +1043,7 @@ dependencies = [ name = "keygen_bls" version = "2.0.0" dependencies = [ + "ark-bls12-381", "concordium_base", "ff", "hex", diff --git a/rust-bins/Cargo.lock b/rust-bins/Cargo.lock index cac36f6eb..12e1ca0dc 100644 --- a/rust-bins/Cargo.lock +++ b/rust-bins/Cargo.lock @@ -1434,6 +1434,7 @@ dependencies = [ name = "keygen_bls" version = "2.0.0" dependencies = [ + "ark-bls12-381", "concordium_base", "ff", "hex", diff --git a/rust-src/Cargo.lock b/rust-src/Cargo.lock index 58bfae1c7..7441b5f04 100644 --- a/rust-src/Cargo.lock +++ b/rust-src/Cargo.lock @@ -613,7 +613,6 @@ dependencies = [ "num-traits", "pbkdf2 0.11.0", "pprof", - "rand 0.7.3", "rand 0.8.5", "rayon", "rust_decimal", @@ -1297,6 +1296,7 @@ dependencies = [ name = "keygen_bls" version = "2.0.0" dependencies = [ + "ark-bls12-381", "concordium_base", "ff", "hex", @@ -1789,7 +1789,6 @@ dependencies = [ "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc", - "rand_pcg", ] [[package]] @@ -1850,15 +1849,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", -] - [[package]] name = "rand_xorshift" version = "0.2.0" diff --git a/rust-src/concordium_base/Cargo.toml b/rust-src/concordium_base/Cargo.toml index 3320d30cd..6c4447b2c 100644 --- a/rust-src/concordium_base/Cargo.toml +++ b/rust-src/concordium_base/Cargo.toml @@ -74,10 +74,6 @@ features = ["derive-serde"] version = "1" path = "../concordium_base_derive" -[patch.crates-io] -rand = { git = "https://github.com/rust-random/rand.git", tag = "0.8.5"} -# rand_core = { version = "0.6" } - [features] default = [] ffi = [] @@ -86,7 +82,7 @@ encryption = ["cbc", "aes", "base64", "pbkdf2", "hmac"] [dev-dependencies] criterion = "0.4" -rand = {version = "0.7", features = ["small_rng"]} +rand = {version = "0.8", features = ["small_rng"]} pprof = { version = "0.11", features = ["flamegraph", "criterion"] } [[bench]] diff --git a/rust-src/concordium_base/benches/aggr_dlog_commit_message.rs b/rust-src/concordium_base/benches/aggr_dlog_commit_message.rs index 84e14fa66..48a5066fc 100644 --- a/rust-src/concordium_base/benches/aggr_dlog_commit_message.rs +++ b/rust-src/concordium_base/benches/aggr_dlog_commit_message.rs @@ -1,11 +1,13 @@ +use ark_bls12_381::G1Projective; use concordium_base::{ - curve_arithmetic::*, + curve_arithmetic::{arkworks_instances::ArkGroup, *}, sigma_protocols::{aggregate_dlog::*, common::*}, }; use criterion::*; -use pairing::bls12_381::G1; use rand::*; +type G1 = ArkGroup; + /// Benchmark the aggregate dlog sigma protocol fn bench_aggr_dlog_commit_message(c: &mut Criterion) { let mut csprng = thread_rng(); diff --git a/rust-src/concordium_base/benches/aggregate_signatures.rs b/rust-src/concordium_base/benches/aggregate_signatures.rs index 366a23143..fa0b4c8a5 100644 --- a/rust-src/concordium_base/benches/aggregate_signatures.rs +++ b/rust-src/concordium_base/benches/aggregate_signatures.rs @@ -1,8 +1,9 @@ use concordium_base::aggregate_sig::*; use criterion::*; -use pairing::bls12_381::Bls12; use rand::{thread_rng, Rng}; +type Bls12 = ark_ec::bls12::Bls12; + macro_rules! rand_m_of_length { ($length:expr, $rng:expr) => {{ let mut m: Vec = Vec::with_capacity($length); diff --git a/rust-src/concordium_base/benches/bulletproofs.rs b/rust-src/concordium_base/benches/bulletproofs.rs index 6716a8ff8..51ee92e32 100644 --- a/rust-src/concordium_base/benches/bulletproofs.rs +++ b/rust-src/concordium_base/benches/bulletproofs.rs @@ -3,21 +3,23 @@ #[macro_use] extern crate criterion; +use ark_bls12_381::{Fr, G1Projective}; use concordium_base::{ bulletproofs::{inner_product_proof::*, range_proof::*, utils::Generators}, - curve_arithmetic::*, + curve_arithmetic::{ + arkworks_instances::{ArkField, ArkGroup}, + *, + }, id::id_proof_types::ProofVersion, pedersen_commitment::*, random_oracle::RandomOracle, }; use criterion::Criterion; -use ff::Field; -use pairing::bls12_381::{Fr, G1}; use rand::*; use std::time::Duration; -type SomeCurve = G1; -type SomeField = Fr; +type SomeCurve = ArkGroup; +type SomeField = ArkField; pub fn prove_verify_benchmarks(c: &mut Criterion) { let mut group = c.benchmark_group("Range Proof"); diff --git a/rust-src/concordium_base/benches/commitment_to_share.rs b/rust-src/concordium_base/benches/commitment_to_share.rs index dba0f21d8..e6e5f645f 100644 --- a/rust-src/concordium_base/benches/commitment_to_share.rs +++ b/rust-src/concordium_base/benches/commitment_to_share.rs @@ -1,10 +1,14 @@ +use ark_bls12_381::G1Projective; use concordium_base::{ - curve_arithmetic::*, id::utils::commitment_to_share, pedersen_commitment::Commitment, + curve_arithmetic::{arkworks_instances::ArkGroup, *}, + id::utils::commitment_to_share, + pedersen_commitment::Commitment, }; use criterion::*; -use pairing::bls12_381::G1; use rand::*; +type G1 = ArkGroup; + fn bench_commitment_to_share(c: &mut Criterion) { let mut csprng = thread_rng(); diff --git a/rust-src/concordium_base/benches/eddsa_benchmarks.rs b/rust-src/concordium_base/benches/eddsa_benchmarks.rs index 560b9976d..a626e4bef 100644 --- a/rust-src/concordium_base/benches/eddsa_benchmarks.rs +++ b/rust-src/concordium_base/benches/eddsa_benchmarks.rs @@ -9,17 +9,13 @@ use rand::*; pub fn bench_from_bytes(c: &mut Criterion) { let mut csprng = thread_rng(); - let n = 32; - let mut a: Vec = Vec::with_capacity(n); - for _ in 0..n { - a.push(csprng.gen::()); - } - let ca = a.clone(); - c.bench_function("PublicKey::from_bytes {}", move |b| { - b.iter(|| PublicKey::from_bytes(&a).is_ok()) + let mut a = [0u8; 32]; + csprng.fill_bytes(&mut a); + c.bench_function("VerifyingKey::from_bytes {}", move |b| { + b.iter(|| VerifyingKey::from_bytes(&a).is_ok()) }); - c.bench_function("SecretKey::from_bytes {}", move |b| { - b.iter(|| SecretKey::from_bytes(&ca).is_ok()) + c.bench_function("SigningKey::from_bytes {}", move |b| { + b.iter(|| SigningKey::from_bytes(&a)) }); } @@ -32,13 +28,10 @@ pub fn bench_sign(c: &mut Criterion) { } let d = a.clone(); - let sk = SecretKey::generate(&mut csprng); - let pk = PublicKey::from(&sk); - let expanded_sk = ExpandedSecretKey::from(&sk); - let sig = expanded_sk.sign(a.as_slice(), &pk); - c.bench_function("sign {}", move |b| { - b.iter(|| expanded_sk.sign(a.as_slice(), &pk)) - }); + let signing = SigningKey::generate(&mut csprng); + let pk = signing.verifying_key(); + let sig = signing.sign(a.as_slice()); + c.bench_function("sign {}", move |b| b.iter(|| signing.sign(a.as_slice()))); c.bench_function("verify{}", move |b| { b.iter(|| pk.verify(d.as_slice(), &sig)) }); diff --git a/rust-src/concordium_base/benches/elgamal_benchmarks.rs b/rust-src/concordium_base/benches/elgamal_benchmarks.rs index 1e8a0fd28..6481109f8 100644 --- a/rust-src/concordium_base/benches/elgamal_benchmarks.rs +++ b/rust-src/concordium_base/benches/elgamal_benchmarks.rs @@ -1,3 +1,4 @@ +use ark_bls12_381::G1Projective; use rand::*; #[macro_use] @@ -5,12 +6,17 @@ extern crate criterion; use criterion::Criterion; -use concordium_base::elgamal::*; - -use concordium_base::curve_arithmetic::Curve; -use ff::PrimeField; -use pairing::bls12_381::{Fr, G1}; -use std::time::Duration; +use concordium_base::{ + curve_arithmetic::{ + arkworks_instances::{ArkField, ArkGroup}, + Curve, + }, + elgamal::*, +}; +use std::{str::FromStr, time::Duration}; + +type G1 = ArkGroup; +type Fr = ArkField; pub fn baby_step_giant_step_table_bench(c: &mut Criterion) { let mut csprng = thread_rng(); diff --git a/rust-src/concordium_base/benches/encrypted_transfers_benchmarks.rs b/rust-src/concordium_base/benches/encrypted_transfers_benchmarks.rs index f41d00197..3702f5686 100644 --- a/rust-src/concordium_base/benches/encrypted_transfers_benchmarks.rs +++ b/rust-src/concordium_base/benches/encrypted_transfers_benchmarks.rs @@ -1,3 +1,4 @@ +use ark_bls12_381::G1Projective; use rand::*; #[macro_use] @@ -5,19 +6,20 @@ extern crate criterion; use concordium_base::{ common::types::Amount, - curve_arithmetic::Value, + curve_arithmetic::{arkworks_instances::ArkGroup, Value}, elgamal::{PublicKey, SecretKey}, encrypted_transfers::proofs::*, id::types::GlobalContext, random_oracle::*, }; use criterion::Criterion; -use pairing::bls12_381::G1; use std::time::Duration; +type G1 = ArkGroup; + pub fn generate_challenge_prefix(csprng: &mut R) -> Vec { // length of the challenge - let l = csprng.gen_range(0, 1000); + let l = csprng.gen_range(0..1000); let mut challenge_prefix = vec![0; l]; for v in challenge_prefix.iter_mut() { *v = csprng.gen(); @@ -35,7 +37,7 @@ pub fn enc_trans_bench(c: &mut Criterion) { let pk_receiver = PublicKey::from(&sk_receiver); let s = csprng.gen::(); // amount on account. - let a = csprng.gen_range(0, s); // amount to send + let a = csprng.gen_range(0..s); // amount to send let m = 2; // 2 chunks let n = 32; @@ -53,6 +55,7 @@ pub fn enc_trans_bench(c: &mut Criterion) { let context_clone = context.clone(); let sk_clone = sk_sender.clone(); + let mut csprng_clone = csprng.clone(); c.bench_function( &format!("{}: Create transaction with proofs", module_path!()), move |b| { @@ -67,7 +70,7 @@ pub fn enc_trans_bench(c: &mut Criterion) { &S, Amount::from_micro_ccd(s), Amount::from_micro_ccd(a), - &mut csprng, + &mut csprng_clone, ) .expect("Could not produce proof."); }) @@ -121,7 +124,7 @@ pub fn sec_to_pub_bench(c: &mut Criterion) { let pk = PublicKey::from(&sk); let s = csprng.gen::(); // amount on account. - let a = csprng.gen_range(0, s); // amount to send + let a = csprng.gen_range(0..s); // amount to send let m = 2; // 2 chunks let n = 32; @@ -139,6 +142,7 @@ pub fn sec_to_pub_bench(c: &mut Criterion) { let context_clone = context.clone(); let sk_clone = sk.clone(); + let mut csprng_clone = csprng.clone(); c.bench_function( &format!( "{}: Create sec to pub transaction with proofs", @@ -155,7 +159,7 @@ pub fn sec_to_pub_bench(c: &mut Criterion) { &S, Amount::from_micro_ccd(s), Amount::from_micro_ccd(a), - &mut csprng, + &mut csprng_clone, ) .expect("Could not produce proof."); }) diff --git a/rust-src/concordium_base/benches/hash_bench.rs b/rust-src/concordium_base/benches/hash_bench.rs index c072af72c..e60a9fc69 100644 --- a/rust-src/concordium_base/benches/hash_bench.rs +++ b/rust-src/concordium_base/benches/hash_bench.rs @@ -1,11 +1,13 @@ #[macro_use] extern crate criterion; -use concordium_base::curve_arithmetic::*; +use ark_bls12_381::G1Projective; +use concordium_base::curve_arithmetic::{arkworks_instances::ArkGroup, Curve}; use criterion::Criterion; -use pairing::bls12_381::G1; use rand::*; +type G1 = ArkGroup; + macro_rules! rand_m_of_length { ($length:expr, $rng:expr) => {{ let mut m: Vec = Vec::with_capacity($length); diff --git a/rust-src/concordium_base/benches/msm_bench.rs b/rust-src/concordium_base/benches/msm_bench.rs index 742cacc50..a329a9c6e 100644 --- a/rust-src/concordium_base/benches/msm_bench.rs +++ b/rust-src/concordium_base/benches/msm_bench.rs @@ -3,13 +3,15 @@ #[macro_use] extern crate criterion; -use concordium_base::curve_arithmetic::*; +use ark_bls12_381::G1Projective; +use concordium_base::curve_arithmetic::{arkworks_instances::ArkGroup, *}; use criterion::Criterion; use curve25519_dalek_ng::{ristretto::RistrettoPoint, traits::VartimePrecomputedMultiscalarMul}; -use pairing::bls12_381::G1; use rand::*; use std::time::Duration; +type G1 = ArkGroup; + const N: usize = 512; pub fn ccd_msm_benchmarks(c: &mut Criterion) { diff --git a/rust-src/concordium_base/benches/multiexp_bench.rs b/rust-src/concordium_base/benches/multiexp_bench.rs index 5b673f6d0..22c844a21 100644 --- a/rust-src/concordium_base/benches/multiexp_bench.rs +++ b/rust-src/concordium_base/benches/multiexp_bench.rs @@ -1,11 +1,13 @@ #[macro_use] extern crate criterion; -use concordium_base::curve_arithmetic::*; +use ark_bls12_381::G1Projective; +use concordium_base::curve_arithmetic::{arkworks_instances::ArkGroup, *}; use criterion::Criterion; -use pairing::bls12_381::G1; use rand::*; +type G1 = ArkGroup; + pub fn bench_multiexp(c: &mut Criterion) { let mut csprng = thread_rng(); let m = 3; diff --git a/rust-src/concordium_base/benches/range_proof_bench.rs b/rust-src/concordium_base/benches/range_proof_bench.rs index 6787b4914..0e1ecf3fe 100644 --- a/rust-src/concordium_base/benches/range_proof_bench.rs +++ b/rust-src/concordium_base/benches/range_proof_bench.rs @@ -3,14 +3,8 @@ #[macro_use] extern crate criterion; -use ark_ec::{ - hashing::{ - curve_maps::wb::{WBConfig, WBMap}, - map_to_curve_hasher::MapToCurveBasedHasher, - HashToCurve, - }, - short_weierstrass::Projective, -}; +use ark_bls12_381::G1Projective; +use ark_ec::hashing::HashToCurve; use ark_ff::field_hashers::DefaultFieldHasher; use concordium_base::{ bulletproofs::{range_proof::*, utils::Generators}, @@ -21,13 +15,10 @@ use concordium_base::{ }; use criterion::Criterion; use curve25519_dalek::ristretto::RistrettoPoint; -use pairing::bls12_381::G1; use pprof::criterion::Output; use rand::*; use std::time::Duration; -// type SomeCurve = G1; - pub fn prove_verify_benchmarks(c: &mut Criterion) { let mut group = c.benchmark_group("Range Proof"); @@ -132,8 +123,8 @@ criterion_group!( pprof::criterion::PProfProfiler::new(100, Output::Flamegraph(None)) ); targets = - prove_verify_benchmarks::, - prove_verify_benchmarks::, + prove_verify_benchmarks::>, + // prove_verify_benchmarks::, prove_verify_benchmarks::, prove_verify_benchmarks::> ); diff --git a/rust-src/concordium_base/benches/range_proof_dalek_bench.rs b/rust-src/concordium_base/benches/range_proof_dalek_bench.rs index 00e2ba784..31768536f 100644 --- a/rust-src/concordium_base/benches/range_proof_dalek_bench.rs +++ b/rust-src/concordium_base/benches/range_proof_dalek_bench.rs @@ -2,9 +2,7 @@ use criterion::*; use pprof::criterion::{Output, PProfProfiler}; -use rand::Rng; -// use rand::*; -use rand_core::*; +use rand::{rngs::OsRng, Rng}; use std::time::Duration; use bulletproofs::{BulletproofGens, PedersenGens, RangeProof}; @@ -33,7 +31,7 @@ pub fn prove_verify_benchmarks(c: &mut Criterion) { let bp_gens = BulletproofGens::new(n, m); let mut rng = rand::thread_rng(); let (min, max) = (0u64, ((1u128 << n) - 1) as u64); - let values: Vec = (0..m).map(|_| rng.gen_range(min, max)).collect(); + let values: Vec = (0..m).map(|_| rng.gen_range(min..max)).collect(); let blindings: Vec = (0..m).map(|_| Scalar::random(&mut rng)).collect(); let mut transcript = Transcript::new(b"AggregateRangeProofBenchmark"); let (proof, value_commitments) = diff --git a/rust-src/concordium_base/benches/serialization_benches.rs b/rust-src/concordium_base/benches/serialization_benches.rs index 3449e5c5d..2add0b8a9 100644 --- a/rust-src/concordium_base/benches/serialization_benches.rs +++ b/rust-src/concordium_base/benches/serialization_benches.rs @@ -3,14 +3,17 @@ #[macro_use] extern crate criterion; +use ark_bls12_381::{G1Projective, G2Projective}; use concordium_base::{ common::{Deserial, Serial}, - curve_arithmetic::*, + curve_arithmetic::{arkworks_instances::ArkGroup, *}, }; use criterion::Criterion; -use pairing::bls12_381::{G1, G2}; use rand::*; +type G1 = ArkGroup; +type G2 = ArkGroup; + pub fn bench_serialize_g1(c: &mut Criterion) { let mut csprng = thread_rng(); let elem = G1::generate(&mut csprng); diff --git a/rust-src/concordium_base/benches/set_proof_bench.rs b/rust-src/concordium_base/benches/set_proof_bench.rs index cd2b1287e..3dd9e5d3f 100644 --- a/rust-src/concordium_base/benches/set_proof_bench.rs +++ b/rust-src/concordium_base/benches/set_proof_bench.rs @@ -2,18 +2,20 @@ #[macro_use] extern crate criterion; +use ark_bls12_381::G1Projective; use concordium_base::{ bulletproofs::{set_membership_proof, set_non_membership_proof, utils::Generators}, - curve_arithmetic::*, + curve_arithmetic::{arkworks_instances::ArkGroup, *}, id::id_proof_types::ProofVersion, pedersen_commitment::{CommitmentKey, Randomness}, random_oracle::RandomOracle, }; use criterion::{BenchmarkId, Criterion}; -use pairing::bls12_381::G1; use rand::*; use std::time::Duration; +type G1 = ArkGroup; + #[allow(non_snake_case)] pub fn bench_set_proofs(c: &mut Criterion) { let mut group = c.benchmark_group("Set Proofs"); @@ -34,7 +36,7 @@ pub fn bench_set_proofs(c: &mut Criterion) { } // Let w be an element in the set - let w_index = rng.gen_range(0, n); + let w_index = rng.gen_range(0..n); let w = the_set[w_index]; // Commit to v diff --git a/rust-src/concordium_base/benches/verify_cdi.rs b/rust-src/concordium_base/benches/verify_cdi.rs index 260c687ac..dd4874335 100644 --- a/rust-src/concordium_base/benches/verify_cdi.rs +++ b/rust-src/concordium_base/benches/verify_cdi.rs @@ -1,8 +1,10 @@ +use ark_bls12_381::G1Projective; use concordium_base::{ common::{ types::{KeyIndex, KeyPair, TransactionTime}, *, }, + curve_arithmetic::arkworks_instances::ArkGroup, dodis_yampolskiy_prf as prf, elgamal::{PublicKey, SecretKey}, id::{ @@ -18,10 +20,12 @@ use concordium_base::{ use criterion::*; use ed25519_dalek as ed25519; use either::Either::Left; -use pairing::bls12_381::{Bls12, G1}; use rand::*; use std::{collections::BTreeMap, convert::TryFrom, io::Cursor}; +type G1 = ArkGroup; +type Bls12 = ark_ec::bls12::Bls12; + type ExampleAttribute = AttributeKind; type ExampleAttributeList = AttributeList; @@ -35,7 +39,7 @@ fn bench_parts(c: &mut Criterion) { let ip_secret_key = concordium_base::ps_sig::SecretKey::::generate(20, &mut csprng); let ip_public_key = concordium_base::ps_sig::PublicKey::from(&ip_secret_key); - let keypair = ed25519::Keypair::generate(&mut csprng); + let keypair = ed25519::SigningKey::generate(&mut csprng); let ah_info = CredentialHolderInfo:: { id_cred: IdCredentials::generate(&mut csprng), @@ -83,7 +87,7 @@ fn bench_parts(c: &mut Criterion) { ip_identity: IpIdentity(88), ip_description: mk_dummy_description("IP88".to_string()), ip_verify_key: ip_public_key, - ip_cdi_verify_key: keypair.public, + ip_cdi_verify_key: keypair.verifying_key(), }; let prf_key = prf::SecretKey::generate(&mut csprng); @@ -148,7 +152,7 @@ fn bench_parts(c: &mut Criterion) { &alist, EXPIRY, &ip_secret_key, - &keypair.secret, + &keypair.to_bytes(), ); let (ip_sig, initial_cdi) = ver_ok.unwrap(); @@ -263,7 +267,7 @@ fn bench_parts(c: &mut Criterion) { &id_object.alist, EXPIRY, &ip_secret_key, - &keypair.secret, + &keypair.to_bytes(), ) .unwrap() }) diff --git a/rust-src/concordium_base/src/aggregate_sig/mod.rs b/rust-src/concordium_base/src/aggregate_sig/mod.rs index 0a4ea9cec..d2133a889 100644 --- a/rust-src/concordium_base/src/aggregate_sig/mod.rs +++ b/rust-src/concordium_base/src/aggregate_sig/mod.rs @@ -441,10 +441,10 @@ mod test { let mut ms: Vec<[u8; 8]> = (0..signers).map(|x| x.to_le_bytes()).collect(); // Make a duplication in the messages - let random_idx1: usize = rng.gen_range(0, SIGNERS); - let mut random_idx2: usize = rng.gen_range(0, SIGNERS); + let random_idx1: usize = rng.gen_range(0..SIGNERS); + let mut random_idx2: usize = rng.gen_range(0..SIGNERS); while random_idx1 == random_idx2 { - random_idx2 = rng.gen_range(0, SIGNERS) + random_idx2 = rng.gen_range(0..SIGNERS) } ms[random_idx1] = ms[random_idx2]; let vs: Vec<(&[u8], ())> = ms.iter().map(|x| (&x[..], ())).collect(); diff --git a/rust-src/concordium_base/src/cis2_types.rs b/rust-src/concordium_base/src/cis2_types.rs index 715333ab0..faae88c47 100644 --- a/rust-src/concordium_base/src/cis2_types.rs +++ b/rust-src/concordium_base/src/cis2_types.rs @@ -1125,7 +1125,10 @@ mod test { #[test] fn test_serialize_random_token_amount() { - let seed = [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + let seed = [ + 1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, + ]; let mut rng = SmallRng::from_seed(seed); for n in (0..1000).map(|_| rng.next_u64()) { @@ -1146,7 +1149,10 @@ mod test { "Incorrect amount parse." ); - let seed = [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + let seed = [ + 1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, + ]; let mut rng = SmallRng::from_seed(seed); for n in (0..1000).map(|_| rng.next_u64()) { diff --git a/rust-src/concordium_base/src/common/serialize.rs b/rust-src/concordium_base/src/common/serialize.rs index 4ce1950bc..93a1d78b0 100644 --- a/rust-src/concordium_base/src/common/serialize.rs +++ b/rust-src/concordium_base/src/common/serialize.rs @@ -903,7 +903,9 @@ pub(crate) fn base16_decode_array<'de, D: Deserializer<'de>, const N: usize>( fn visit_str(self, v: &str) -> Result { let bytes = decode(v).map_err(de::Error::custom)?; - bytes.try_into().map_err(|_|de::Error::custom("Unexpected array length.")) + bytes + .try_into() + .map_err(|_| de::Error::custom("Unexpected array length.")) } } diff --git a/rust-src/concordium_base/src/common/types.rs b/rust-src/concordium_base/src/common/types.rs index ecec2ba5c..3b3111063 100644 --- a/rust-src/concordium_base/src/common/types.rs +++ b/rust-src/concordium_base/src/common/types.rs @@ -499,9 +499,7 @@ pub struct KeyPair { } impl KeyPair { - pub fn public(&self) -> ed25519_dalek::VerifyingKey { - self.inner.verifying_key() - } + pub fn public(&self) -> ed25519_dalek::VerifyingKey { self.inner.verifying_key() } } mod key_pair_json { @@ -576,7 +574,7 @@ mod tests { let num_elems = rng.gen_range(0..200); let sig = Signature { sig: Uniform::new_inclusive(0, 255u8) - .sample_iter(rng) + .sample_iter(rng.clone()) .take(num_elems) .collect(), }; diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 0f9faed82..5fc7f4d31 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -1,5 +1,5 @@ use core::fmt; -use std::str::FromStr; +use std::{str::FromStr}; use crate::common::{Deserial, Serial}; @@ -61,6 +61,10 @@ impl Field for ArkField { fn inverse(&self) -> Option { self.0.inverse().map(|x| x.into()) } } +impl ArkField { + pub fn into_ark(&self) -> &F { &self.0 } +} + impl PrimeField for ArkField { const CAPACITY: u32 = Self::NUM_BITS - 1; const NUM_BITS: u32 = F::MODULUS_BIT_SIZE; @@ -68,7 +72,7 @@ impl PrimeField for ArkField { fn into_repr(self) -> Vec { self.0.into_bigint().as_ref().to_vec() } fn from_repr(repr: &[u64]) -> Result { - let mut buffer = Vec::new(); + let mut buffer = Vec::with_capacity(8 * repr.len()); for u in repr { buffer.extend(u.to_le_bytes()); } @@ -159,7 +163,25 @@ impl> Curve for ArkGroup { fn scalar_from_u64(n: u64) -> Self::Scalar { ArkField(G::ScalarField::from(n)) } fn scalar_from_bytes>(bs: A) -> Self::Scalar { - ::from_le_bytes_mod_order(bs.as_ref()).into() + // Traverse at most 4 8-byte chunks, for a total of 256 bits. + // The top-most two bits in the last chunk are set to 0. + let s = num::integer::div_ceil(Self::Scalar::CAPACITY, 8); + println!("{:?}", Self::Scalar::NUM_BITS); + println!("{:?}", Self::Scalar::CAPACITY); + println!("{:?}", s); + let mut fr = Vec::with_capacity(s as usize); + for chunk in bs.as_ref().chunks(8).take(s as usize) { + let mut v = [0u8; 8]; + v[..chunk.len()].copy_from_slice(chunk); + println!("{:?}", v); + fr.push(u64::from_le_bytes(v)); + } + // unset two topmost bits in the last read u64. + *fr.last_mut().expect("Non empty vector expected") &= !(1u64 << 63 | 1u64 << 62); + // fr[3] &= !(1u64 << 63 | 1u64 << 62); + ::from_repr(&fr) + .expect("The scalar with top two bits erased should be valid.") + } fn hash_to_group(m: &[u8]) -> Self { diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 9a74f0f5b..9e40d2bec 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -27,19 +27,6 @@ impl ArkCurveConfig for Projective { const GROUP_ELEMENT_LENGTH: usize = 48; const SCALAR_LENGTH: usize = 32; } - -// impl ArkCurveConfig> for -// Projective> { type Hasher = MapToCurveBasedHasher< -// Projective>, -// DefaultFieldHasher, -// WBMap>, -// >; - -// const DOMAIN_STRING: &'static str = "BLS12381G1"; -// const GROUP_ELEMENT_LENGTH: usize = 48; -// const SCALAR_LENGTH: usize = 32; -// } - impl ArkCurveConfig for Projective { type Hasher = MapToCurveBasedHasher, WBMap>; diff --git a/rust-src/concordium_base/src/ecvrf/mod.rs b/rust-src/concordium_base/src/ecvrf/mod.rs index 2da0fae6f..c365b3518 100644 --- a/rust-src/concordium_base/src/ecvrf/mod.rs +++ b/rust-src/concordium_base/src/ecvrf/mod.rs @@ -262,7 +262,7 @@ mod tests { // Test serialization of generated secret scalar let x = expanded_sk.key; - assert_eq!(x, Scalar::from_bits(x_bytes)); + assert_eq!(x, Scalar::from_bytes_mod_order(x_bytes)); // Test serialization of proof let proof = expanded_sk.prove(&pk, &alpha_bytes); diff --git a/rust-src/concordium_base/src/ecvrf/proof.rs b/rust-src/concordium_base/src/ecvrf/proof.rs index 665efa9ac..4db65346f 100644 --- a/rust-src/concordium_base/src/ecvrf/proof.rs +++ b/rust-src/concordium_base/src/ecvrf/proof.rs @@ -34,14 +34,16 @@ pub struct Proof(pub EdwardsPoint, pub Scalar, pub Scalar); impl Serial for Proof { #[inline] fn serial(&self, x: &mut B) { - let c = &self.1.reduce().to_bytes(); + // The scalar is already reduced https://docs.rs/curve25519-dalek/4.1.1/src/curve25519_dalek/scalar.rs.html#211, + // so we just convert it to bytes. + let c = &self.1.to_bytes(); // assert c is within range assert_eq!(c[16..32], [0u8; 16]); x.write_all(&self.0.compress().to_bytes()[..]) .expect("Writing to buffer should succeed."); x.write_all(&c[..16]) .expect("Writing to buffer should succeed."); - x.write_all(&self.2.reduce().to_bytes()[..]) + x.write_all(&self.2.to_bytes()[..]) .expect("Writing to buffer should succeed."); } } diff --git a/rust-src/concordium_base/src/ecvrf/public.rs b/rust-src/concordium_base/src/ecvrf/public.rs index bbb84a62d..188d8968f 100644 --- a/rust-src/concordium_base/src/ecvrf/public.rs +++ b/rust-src/concordium_base/src/ecvrf/public.rs @@ -5,7 +5,7 @@ use core::fmt::Debug; use curve25519_dalek::{ constants, edwards::{CompressedEdwardsY, EdwardsPoint}, - scalar::Scalar, + scalar::{clamp_integer, Scalar}, }; use sha2::{Digest, Sha512}; @@ -94,11 +94,9 @@ impl PublicKey { fn mangle_scalar_bits_and_multiply_by_basepoint_to_produce_public_key( bits: &mut [u8; 32], ) -> PublicKey { - bits[0] &= 0b_1111_1000; - bits[31] &= 0b_0111_1111; - bits[31] |= 0b_0100_0000; + let scalar = Scalar::from_bytes_mod_order(clamp_integer(*bits)); - let point = &Scalar::from_bits(*bits) * &constants::ED25519_BASEPOINT_TABLE; + let point = &scalar * constants::ED25519_BASEPOINT_TABLE; let compressed = point.compress(); PublicKey(compressed, point) @@ -145,7 +143,7 @@ impl PublicKey { // generated nonce and x is the secret key // self should be equal y=b^x - let b_to_s = s * &constants::ED25519_BASEPOINT_TABLE; // should be equal to b^(k+cx) + let b_to_s = s * constants::ED25519_BASEPOINT_TABLE; // should be equal to b^(k+cx) let y_to_c = c * self.1; // y_to_c should be equal to b^(cx) let u = b_to_s - y_to_c; // should equal b^k diff --git a/rust-src/concordium_base/src/ecvrf/secret.rs b/rust-src/concordium_base/src/ecvrf/secret.rs index 633e78912..ba023d794 100644 --- a/rust-src/concordium_base/src/ecvrf/secret.rs +++ b/rust-src/concordium_base/src/ecvrf/secret.rs @@ -3,7 +3,10 @@ use super::{constants::*, errors::*, public::*}; use crate::common::*; use core::fmt::Debug; -use curve25519_dalek::{constants, scalar::Scalar}; +use curve25519_dalek::{ + constants, + scalar::{clamp_integer, Scalar}, +}; use rand::{CryptoRng, Rng}; use sha2::{digest::Digest, Sha512}; use subtle::{Choice, ConstantTimeEq}; @@ -123,12 +126,10 @@ impl From<&SecretKey> for ExpandedSecretKey { lower.copy_from_slice(&hash[00..32]); upper.copy_from_slice(&hash[32..64]); - lower[0] &= 0b_1111_1000; - lower[31] &= 0b_0111_1111; - lower[31] |= 0b_0100_0000; + let scalar = Scalar::from_bytes_mod_order(clamp_integer(lower)); ExpandedSecretKey { - key: Scalar::from_bits(lower), + key: scalar, nonce: upper, } } diff --git a/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs b/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs index e1c17a0f8..301a2460c 100644 --- a/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs +++ b/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs @@ -61,7 +61,7 @@ pub enum PointDecodingError { fn scalar_from_secret_key(secret_key: &impl AsRef<[u8]>) -> Scalar { let mut h = Sha512::new(); - // inspired by this https://docs.rs/ed25519-dalek/latest/src/ed25519_dalek/hazmat.rs.html#61-76 + // inspired by this https://docs.rs/ed25519-dalek/2.1.0/src/ed25519_dalek/hazmat.rs.html#61-76 let mut hash: [u8; 64] = [0u8; 64]; let mut scalar_bytes: [u8; 32] = [0u8; 32]; h.update(secret_key); diff --git a/rust-src/concordium_base/src/elgamal/mod.rs b/rust-src/concordium_base/src/elgamal/mod.rs index b6fc727b1..2451ba01a 100644 --- a/rust-src/concordium_base/src/elgamal/mod.rs +++ b/rust-src/concordium_base/src/elgamal/mod.rs @@ -250,7 +250,7 @@ mod tests { let sk: SecretKey = SecretKey::generate_all(&mut csprng); let pk = PublicKey::from(&sk); for _i in 1..10 { - let n = csprng.gen_range(0, 1000); + let n = csprng.gen_range(0..1000); let mut e = ::Scalar::zero(); let one_scalar = Value::::new(::Scalar::one()); for _ in 0..n { @@ -284,7 +284,7 @@ mod tests { for _i in 1..10 { let scalar = Value::::generate(&mut csprng); - let chunk_size_index: usize = csprng.gen_range(0, possible_chunk_sizes.len()); + let chunk_size_index: usize = csprng.gen_range(0..possible_chunk_sizes.len()); let chunk_size = possible_chunk_sizes[chunk_size_index]; let chunks = value_to_chunks::(&scalar, chunk_size); let retrieved_scalar = chunks_to_value::(&chunks, chunk_size); @@ -308,7 +308,7 @@ mod tests { for _i in 1..2 { let scalar = Value::::generate(&mut csprng); - let chunk_size_index: usize = csprng.gen_range(0, possible_chunk_sizes.len()); + let chunk_size_index: usize = csprng.gen_range(0..possible_chunk_sizes.len()); let chunk_size = possible_chunk_sizes[chunk_size_index]; let m = 1 << (u8::from(chunk_size) - 1); let cipher_pairs = diff --git a/rust-src/concordium_base/src/encrypted_transfers/mod.rs b/rust-src/concordium_base/src/encrypted_transfers/mod.rs index 43e10512e..6caf4a545 100644 --- a/rust-src/concordium_base/src/encrypted_transfers/mod.rs +++ b/rust-src/concordium_base/src/encrypted_transfers/mod.rs @@ -363,7 +363,7 @@ mod tests { let pk_receiver = PublicKey::from(&sk_receiver); let s: u64 = csprng.gen(); // amount on account. - let a = csprng.gen_range(0, s); // amount to send + let a = csprng.gen_range(0..s); // amount to send let m = 2; // 2 chunks let n = 32; @@ -409,7 +409,7 @@ mod tests { let pk_sender = PublicKey::from(&sk_sender); let s: u64 = csprng.gen(); // amount on account. - let a = csprng.gen_range(0, s); // amount to send + let a = csprng.gen_range(0..s); // amount to send let m = 2; // 2 chunks let n = 32; diff --git a/rust-src/concordium_base/src/encrypted_transfers/proofs/generate_proofs.rs b/rust-src/concordium_base/src/encrypted_transfers/proofs/generate_proofs.rs index 283702569..5e79fc057 100644 --- a/rust-src/concordium_base/src/encrypted_transfers/proofs/generate_proofs.rs +++ b/rust-src/concordium_base/src/encrypted_transfers/proofs/generate_proofs.rs @@ -666,7 +666,7 @@ mod test { // Copied from common.rs in sigma_protocols since apparently it is not available pub fn generate_challenge_prefix(csprng: &mut R) -> Vec { // length of the challenge - let l = csprng.gen_range(0, 1000); + let l = csprng.gen_range(0..1000); let mut challenge_prefix = vec![0; l]; for v in challenge_prefix.iter_mut() { *v = csprng.gen(); @@ -685,7 +685,7 @@ mod test { let pk_receiver = PublicKey::from(&sk_receiver); let s = csprng.gen::(); // amount on account. - let a = csprng.gen_range(0, s); // amount to send + let a = csprng.gen_range(0..s); // amount to send let m = 2; // 2 chunks let n = 32; @@ -735,7 +735,7 @@ mod test { let pk = PublicKey::from(&sk); let s = csprng.gen::(); // amount on account. - let a = csprng.gen_range(0, s); // amount to send + let a = csprng.gen_range(0..s); // amount to send let m = 2; // 2 chunks let n = 32; diff --git a/rust-src/concordium_base/src/id/ffi.rs b/rust-src/concordium_base/src/id/ffi.rs index 72c0e8284..ee5f5de72 100644 --- a/rust-src/concordium_base/src/id/ffi.rs +++ b/rust-src/concordium_base/src/id/ffi.rs @@ -559,7 +559,7 @@ fn ip_info_create_helper( // Identity provider CDI verify key. let ip_cdi_verify_key = { let ed_buf = &mut slice_from_c_bytes!(cdi_verify_key_ptr, cdi_verify_key_len); - from_bytes::(ed_buf) + from_bytes::(ed_buf) .context("Unable to create PublicKey instance from byte array at cdi_verify_key_ptr.")? }; diff --git a/rust-src/concordium_base/src/id/identity_provider.rs b/rust-src/concordium_base/src/id/identity_provider.rs index ff0ec3d7e..f07bbc957 100644 --- a/rust-src/concordium_base/src/id/identity_provider.rs +++ b/rust-src/concordium_base/src/id/identity_provider.rs @@ -569,9 +569,7 @@ fn sign_initial_cred_values< hasher.update(&to_bytes(&initial_cred_values)); let to_sign = hasher.finalize(); let signing_key = ed25519_dalek::SigningKey::from(ip_cdi_secret_key); - signing_key - .sign(to_sign.as_ref()) - .into() + signing_key.sign(to_sign.as_ref()).into() } pub fn compute_message>( diff --git a/rust-src/concordium_base/src/id/test.rs b/rust-src/concordium_base/src/id/test.rs index d549cedff..9c4ef5e44 100644 --- a/rust-src/concordium_base/src/id/test.rs +++ b/rust-src/concordium_base/src/id/test.rs @@ -16,6 +16,7 @@ use crate::{ types::*, }, }; +use ed25519::SigningKey; use ed25519_dalek as ed25519; use either::Either::Left; use rand::*; @@ -70,9 +71,11 @@ pub fn test_create_ip_info( let ps_len = (5 + num_ars + max_attrs) as usize; let ip_secret_key = crate::ps_sig::SecretKey::::generate(ps_len, csprng); let ip_verify_key = crate::ps_sig::PublicKey::from(&ip_secret_key); - let keypair = ed25519::Keypair::generate(csprng); - let ip_cdi_verify_key = keypair.public; - let ip_cdi_secret_key = keypair.secret; + let mut secret = [0u8; 32]; + csprng.fill_bytes(&mut secret); + let signing = SigningKey::from_bytes(&secret); + let ip_cdi_verify_key = signing.verifying_key(); + let ip_cdi_secret_key = secret; // Return IpData with public and private keys. IpData { diff --git a/rust-src/concordium_base/src/id/types.rs b/rust-src/concordium_base/src/id/types.rs index 4535abfaa..b71839dbc 100644 --- a/rust-src/concordium_base/src/id/types.rs +++ b/rust-src/concordium_base/src/id/types.rs @@ -2241,9 +2241,7 @@ impl CredentialDataWithSigning for CredentialData { ); self.keys .iter() - .map(|(&idx, kp)| { - (idx, kp.sign(&to_sign).into()) - }) + .map(|(&idx, kp)| (idx, kp.sign(&to_sign).into())) .collect() } } @@ -2276,9 +2274,7 @@ impl InitialAccountDataWithSigning for InitialAccountData { let to_sign = Sha256::digest(to_bytes(pub_info_for_ip)); self.keys .iter() - .map(|(&idx, kp)| { - (idx, kp.sign(&to_sign).into()) - }) + .map(|(&idx, kp)| (idx, kp.sign(&to_sign).into())) .collect() } } @@ -2647,7 +2643,7 @@ mod tests { use rand::thread_rng; let mut csprng = thread_rng(); - let keypair = ed25519::Keypair::generate(&mut csprng); + let keypair = ed25519::SigningKey::generate(&mut csprng); for _ in 0..1000 { let message: &[u8] = b"test"; let signature: AccountOwnershipSignature = keypair.sign(message).into(); @@ -2676,17 +2672,13 @@ mod tests { // Get public key from map let credential_keys = &keypairs.keys[&CredentialIndex { index: 0 }]; let key_pair = &credential_keys.keys[&KeyIndex(0)]; - let public_key = key_pair.public; + let public_key = key_pair.public(); // Check that signature is valid match signature { concordium_std::Signature::Ed25519(signature) => { public_key - .verify( - message, - &ed25519_dalek::Signature::from_bytes(&signature.0) - .expect("Should be able to convert signature"), - ) + .verify(message, &ed25519_dalek::Signature::from_bytes(&signature.0)) .expect("Should be a valid signature"); } _ => assert!(false, "Could not get signature"), diff --git a/rust-src/concordium_base/src/lib.rs b/rust-src/concordium_base/src/lib.rs index 064b02761..4bebcfd4c 100644 --- a/rust-src/concordium_base/src/lib.rs +++ b/rust-src/concordium_base/src/lib.rs @@ -35,7 +35,7 @@ pub mod dodis_yampolskiy_prf; /// We expose the `PublicKey`, `SecretKey`, and `Signature` from the third-party /// `ed25519_dalek` crate here because these types appear in Concordium's API. pub mod ed25519 { - pub use ed25519_dalek::{VerifyingKey as PublicKey, SecretKey, Signature}; + pub use ed25519_dalek::{SecretKey, Signature, VerifyingKey as PublicKey}; } #[cfg(feature = "ffi")] diff --git a/rust-src/concordium_base/src/sigma_protocols/common.rs b/rust-src/concordium_base/src/sigma_protocols/common.rs index 77ff80eb2..92029f48d 100644 --- a/rust-src/concordium_base/src/sigma_protocols/common.rs +++ b/rust-src/concordium_base/src/sigma_protocols/common.rs @@ -339,7 +339,7 @@ pub fn verify( /// Generate a random challenge prefix of random length used for testing. pub fn generate_challenge_prefix(csprng: &mut R) -> Vec { // length of the challenge - let l = csprng.gen_range(0, 1000); + let l = csprng.gen_range(0..1000); let mut challenge_prefix = vec![0; l]; for v in challenge_prefix.iter_mut() { *v = csprng.gen(); diff --git a/rust-src/concordium_base/src/sigma_protocols/enc_trans.rs b/rust-src/concordium_base/src/sigma_protocols/enc_trans.rs index b84f70d0e..af1e1ff26 100644 --- a/rust-src/concordium_base/src/sigma_protocols/enc_trans.rs +++ b/rust-src/concordium_base/src/sigma_protocols/enc_trans.rs @@ -394,7 +394,7 @@ mod tests { coeff: [S.0, encr_exp_base], }; - let a = rng.gen_range(0, s); // amount to send + let a = rng.gen_range(0..s); // amount to send let s_prime = s - a; let a_chunks = CHUNK_SIZE.u64_to_chunks(a); let s_prime_chunks = CHUNK_SIZE.u64_to_chunks(s_prime); @@ -478,7 +478,7 @@ mod tests { fn generate_challenge_prefix(csprng: &mut R) -> Vec { // length of the challenge - let l = csprng.gen_range(0, 1000); + let l = csprng.gen_range(0..1000); let mut challenge_prefix = vec![0; l]; for v in challenge_prefix.iter_mut() { *v = csprng.gen(); diff --git a/rust-src/concordium_base/src/sigma_protocols/vcom_eq.rs b/rust-src/concordium_base/src/sigma_protocols/vcom_eq.rs index f0a981fa8..dc21843cb 100644 --- a/rust-src/concordium_base/src/sigma_protocols/vcom_eq.rs +++ b/rust-src/concordium_base/src/sigma_protocols/vcom_eq.rs @@ -317,8 +317,8 @@ mod tests { i += 1; } let wrong_comm = Commitment::generate(csprng); - let index_wrong_comm: IndexType = csprng.gen_range(0, 6); - let index_wrong_gi: usize = csprng.gen_range(0, 10); + let index_wrong_comm: IndexType = csprng.gen_range(0..6); + let index_wrong_gi: usize = csprng.gen_range(0..10); let mut wrong_comms = comms.clone(); wrong_comms.insert(index_wrong_comm, wrong_comm); let mut wrong_gis = gis.clone(); diff --git a/rust-src/concordium_base/src/transactions.rs b/rust-src/concordium_base/src/transactions.rs index 32dfdc8f7..0b70fb410 100644 --- a/rust-src/concordium_base/src/transactions.rs +++ b/rust-src/concordium_base/src/transactions.rs @@ -1525,7 +1525,12 @@ impl From<&AccountKeys> for AccountAccessStructure { keys: v .keys .iter() - .map(|(ki, kp)| (*ki, VerifyKey::Ed25519VerifyKey(kp.as_ref().verifying_key()))) + .map(|(ki, kp)| { + ( + *ki, + VerifyKey::Ed25519VerifyKey(kp.as_ref().verifying_key()), + ) + }) .collect(), threshold: v.threshold, }) @@ -3179,11 +3184,11 @@ mod tests { fn test_transaction_signature_check() { let mut rng = rand::thread_rng(); let mut keys = BTreeMap::>::new(); - let bound: usize = rng.gen_range(1, 20); + let bound: usize = rng.gen_range(1..20); for _ in 0..bound { let c_idx = CredentialIndex::from(rng.gen::()); if keys.get(&c_idx).is_none() { - let inner_bound: usize = rng.gen_range(1, 20); + let inner_bound: usize = rng.gen_range(1..20); let mut cred_keys = BTreeMap::new(); for _ in 0..inner_bound { let k_idx = KeyIndex::from(rng.gen::()); @@ -3195,12 +3200,12 @@ mod tests { let hash = TransactionSignHash::new(rng.gen()); let sig = keys.sign_transaction_hash(&hash); let threshold = - AccountThreshold::try_from(rng.gen_range(1, (keys.len() + 1) as u8)).unwrap(); + AccountThreshold::try_from(rng.gen_range(1..(keys.len() + 1) as u8)).unwrap(); let pub_keys = keys .iter() .map(|(&ci, keys)| { let threshold = - SignatureThreshold::try_from(rng.gen_range(1, keys.len() + 1) as u8).unwrap(); + SignatureThreshold::try_from(rng.gen_range(1..keys.len() + 1) as u8).unwrap(); let keys = keys .iter() .map(|(&ki, kp)| (ki, VerifyKey::from(kp))) diff --git a/rust-src/concordium_base/src/web3id/mod.rs b/rust-src/concordium_base/src/web3id/mod.rs index 75ce916ca..faf74a192 100644 --- a/rust-src/concordium_base/src/web3id/mod.rs +++ b/rust-src/concordium_base/src/web3id/mod.rs @@ -1014,7 +1014,9 @@ impl Web3IdSigner for crate::common::types::KeyPair { } impl Web3IdSigner for ed25519_dalek::SecretKey { - fn id(&self) -> ed25519_dalek::VerifyingKey { ed25519_dalek::SigningKey::from(self).verifying_key() } + fn id(&self) -> ed25519_dalek::VerifyingKey { + ed25519_dalek::SigningKey::from(self).verifying_key() + } fn sign(&self, msg: &impl AsRef<[u8]>) -> ed25519_dalek::Signature { let expanded: ed25519_dalek::SigningKey = self.into(); @@ -1164,8 +1166,9 @@ impl TryFrom anyhow::bail!("Only Web3 credentials are supported.") }; anyhow::ensure!(entrypoint == "credentialEntry", "Incorrect entrypoint."); - let holder_id = - CredentialHolderId::new(ed25519_dalek::VerifyingKey::from_bytes(parameter.as_ref().try_into()?)?); + let holder_id = CredentialHolderId::new(ed25519_dalek::VerifyingKey::from_bytes( + parameter.as_ref().try_into()?, + )?); // Just validate the issuer field. { @@ -1782,6 +1785,7 @@ mod tests { }; use anyhow::Context; use chrono::TimeZone; + use ed25519_dalek::ed25519::signature::Keypair; use rand::Rng; use std::marker::PhantomData; @@ -1810,7 +1814,7 @@ mod tests { .collect(), network: Network::Testnet, contract: contract_1, - credential: CredentialHolderId::new(signer_1.public), + credential: CredentialHolderId::new(signer_1.verifying_key()), statement: vec![ AtomicStatement::AttributeInRange { statement: AttributeInRangeStatement { @@ -1845,7 +1849,7 @@ mod tests { .collect(), network: Network::Testnet, contract: contract_2, - credential: CredentialHolderId::new(signer_2.public), + credential: CredentialHolderId::new(signer_2.verifying_key()), statement: vec![ AtomicStatement::AttributeInRange { statement: AttributeInRangeStatement { @@ -1908,7 +1912,7 @@ mod tests { ¶ms, &values_1, &randomness_1, - &CredentialHolderId::new(signer_1.public), + &CredentialHolderId::new(signer_1.verifying_key()), &issuer_1, contract_1, ) @@ -1948,7 +1952,7 @@ mod tests { ¶ms, &values_2, &randomness_2, - &CredentialHolderId::new(signer_2.public), + &CredentialHolderId::new(signer_2.verifying_key()), &issuer_2, contract_2, ) @@ -1967,10 +1971,10 @@ mod tests { let public = vec![ CredentialsInputs::Web3 { - issuer_pk: issuer_1.public.into(), + issuer_pk: issuer_1.verifying_key().into(), }, CredentialsInputs::Web3 { - issuer_pk: issuer_2.public.into(), + issuer_pk: issuer_2.verifying_key().into(), }, ]; anyhow::ensure!( @@ -2005,8 +2009,8 @@ mod tests { let params = GlobalContext::generate("Test".into()); let cred_id_exp = ArCurve::generate_scalar(&mut rng); let cred_id = CredentialRegistrationID::from_exponent(¶ms, cred_id_exp); - let signer_1 = ed25519_dalek::Keypair::generate(&mut rng); - let issuer_1 = ed25519_dalek::Keypair::generate(&mut rng); + let signer_1 = ed25519_dalek::SigningKey::generate(&mut rng); + let issuer_1 = ed25519_dalek::SigningKey::generate(&mut rng); let contract_1 = ContractAddress::new(1337, 42); let credential_statements = vec![ CredentialStatement::Web3Id { @@ -2019,7 +2023,7 @@ mod tests { .collect(), network: Network::Testnet, contract: contract_1, - credential: CredentialHolderId::new(signer_1.public), + credential: CredentialHolderId::new(signer_1.verifying_key()), statement: vec![ AtomicStatement::AttributeInRange { statement: AttributeInRangeStatement { @@ -2096,7 +2100,7 @@ mod tests { ¶ms, &values_1, &randomness_1, - &CredentialHolderId::new(signer_1.public), + &CredentialHolderId::new(signer_1.verifying_key()), &issuer_1, contract_1, ) @@ -2151,7 +2155,7 @@ mod tests { let public = vec![ CredentialsInputs::Web3 { - issuer_pk: issuer_1.public.into(), + issuer_pk: issuer_1.verifying_key().into(), }, CredentialsInputs::Account { commitments: commitments_2, @@ -2185,8 +2189,8 @@ mod tests { /// Basic test that conversion of Web3IdCredential from/to JSON works. fn test_credential_json() { let mut rng = rand::thread_rng(); - let signer = ed25519_dalek::Keypair::generate(&mut rng); - let issuer = ed25519_dalek::Keypair::generate(&mut rng); + let signer = ed25519_dalek::SigningKey::generate(&mut rng); + let issuer = ed25519_dalek::SigningKey::generate(&mut rng); let mut randomness = BTreeMap::new(); randomness.insert( 0.to_string(), @@ -2213,7 +2217,7 @@ mod tests { ); let cred = Web3IdCredential:: { - holder_id: signer.public.into(), + holder_id: signer.verifying_key().into(), network: Network::Testnet, registry: ContractAddress::new(3, 17), credential_type: [ @@ -2224,7 +2228,7 @@ mod tests { .into_iter() .collect(), credential_schema: "http://link/to/schema".into(), - issuer_key: issuer.public.into(), + issuer_key: issuer.verifying_key().into(), valid_from: chrono::Utc.timestamp_millis_opt(17).unwrap(), valid_until: chrono::Utc.timestamp_millis_opt(12345).earliest(), values, diff --git a/rust-src/ed25519_hd_key_derivation/src/lib.rs b/rust-src/ed25519_hd_key_derivation/src/lib.rs index 9f74fb5f2..cda9d18bc 100644 --- a/rust-src/ed25519_hd_key_derivation/src/lib.rs +++ b/rust-src/ed25519_hd_key_derivation/src/lib.rs @@ -1,3 +1,4 @@ +use ed25519_dalek::SignatureError; use hmac::{Hmac, Mac}; use regex::Regex; use sha2::Sha512; @@ -179,6 +180,8 @@ pub fn derive_from_parsed_path(parsed_path: &[u32], seed: &[u8]) -> Result Result { + ) -> Result { let secret_key = self.get_account_signing_key( identity_provider_index, identity_index, credential_counter, )?; - let public_key = PublicKey::from(&secret_key); + let signing = SigningKey::from_bytes(&secret_key); + let public_key = signing.verifying_key(); Ok(public_key) } @@ -250,24 +250,24 @@ impl ConcordiumHdWallet { 0, ])?; let keys = derive_from_parsed_path(&path, &self.seed)?; - Ok(SecretKey::from_bytes(&keys.private_key) - .expect("The byte array has correct length, so this cannot fail.")) + Ok(keys.private_key) } /// Get the public key for the verifiable credential with the given index. /// The public key is used to identify the specific verifiable credential /// within the registry contract. /// Note that this is just a convenience wrapper. The same can be achieved - /// by using [`PublicKey::from`] on the result of + /// by using [`VerifyingKey::from`] on the result of /// [`get_verifiable_credential_signing_key`](Self::get_verifiable_credential_signing_key) pub fn get_verifiable_credential_public_key( &self, issuer: ContractAddress, verifiable_credential_index: u32, - ) -> Result { + ) -> Result { let signing_key = self.get_verifiable_credential_signing_key(issuer, verifiable_credential_index)?; - let public_key = PublicKey::from(&signing_key); + let signing = SigningKey::from_bytes(&signing_key); + let public_key = signing.verifying_key(); Ok(public_key) } @@ -280,8 +280,7 @@ impl ConcordiumHdWallet { ) -> Result { let path = self.make_verifiable_credential_path(&[1])?; let keys = derive_from_parsed_path(&path, &self.seed)?; - Ok(SecretKey::from_bytes(&keys.private_key) - .expect("The byte array has correct length, so this cannot fail.")) + Ok(keys.private_key) } } @@ -398,10 +397,10 @@ mod tests { let signing_key = create_wallet(Net::Mainnet, TEST_SEED_1) .get_account_signing_key(0, 0, 0) .unwrap(); - let expanded_sk = ExpandedSecretKey::from(&signing_key); + let expanded_sk = SigningKey::from_bytes(&signing_key); let data_to_sign = hex::decode("abcd1234abcd5678").unwrap(); - let signature = expanded_sk.sign(&data_to_sign, &pk); + let signature = expanded_sk.sign(&data_to_sign); pk.verify(&data_to_sign, &signature).expect( "The public key should be able to verify the signature, otherwise the keys do not \ @@ -484,10 +483,10 @@ mod tests { .get_account_signing_key(0, 0, 0) .unwrap(); - let expanded_sk = ExpandedSecretKey::from(&signing_key); + let expanded_sk = SigningKey::from_bytes(&signing_key); let data_to_sign = hex::decode("abcd1234abcd5678").unwrap(); - let signature = expanded_sk.sign(&data_to_sign, &pk); + let signature = expanded_sk.sign(&data_to_sign); pk.verify(&data_to_sign, &signature).expect( "The public key should be able to verify the signature, otherwise the keys do not \ @@ -633,10 +632,10 @@ mod tests { let signing_key = wallet .get_verifiable_credential_signing_key(ContractAddress::new(1337, 0), 0) .unwrap(); - let expanded_sk = ExpandedSecretKey::from(&signing_key); + let expanded_sk = SigningKey::from_bytes(&signing_key); let data_to_sign = hex::decode("abcd1234abcd5678").unwrap(); - let signature = expanded_sk.sign(&data_to_sign, &public_key); + let signature = expanded_sk.sign(&data_to_sign); public_key.verify(&data_to_sign, &signature).expect( "The public key should be able to verify the signature, otherwise the keys do not \ @@ -698,10 +697,10 @@ mod tests { let signing_key = wallet .get_verifiable_credential_signing_key(ContractAddress::new(13, 0), 0) .unwrap(); - let expanded_sk = ExpandedSecretKey::from(&signing_key); + let expanded_sk = SigningKey::from_bytes(&signing_key); let data_to_sign = hex::decode("abcd1234abcd5678").unwrap(); - let signature = expanded_sk.sign(&data_to_sign, &public_key); + let signature = expanded_sk.sign(&data_to_sign); public_key.verify(&data_to_sign, &signature).expect( "The public key should be able to verify the signature, otherwise the keys do not \ diff --git a/rust-src/keygen_bls/Cargo.toml b/rust-src/keygen_bls/Cargo.toml index a10d8ba2f..1c9d7d399 100644 --- a/rust-src/keygen_bls/Cargo.toml +++ b/rust-src/keygen_bls/Cargo.toml @@ -11,6 +11,7 @@ sha2 = "0.10" hkdf = "0.12.0" ff = "0.5" hex = "0.4" +ark-bls12-381 = { version = "0.4" } [dependencies.concordium_base] path = "../concordium_base" diff --git a/rust-src/keygen_bls/src/lib.rs b/rust-src/keygen_bls/src/lib.rs index bf56b69ba..4b5339983 100644 --- a/rust-src/keygen_bls/src/lib.rs +++ b/rust-src/keygen_bls/src/lib.rs @@ -1,17 +1,18 @@ //! Generate a private key in a deterministic way from a secret seed and key //! description. -use concordium_base::curve_arithmetic::Curve; -use ff::{Field, PrimeField}; +use ark_bls12_381::{G1Projective, Fr}; +use concordium_base::curve_arithmetic::{Curve, Field, PrimeField, arkworks_instances::{ArkField, ArkGroup}}; use hkdf::Hkdf; -use pairing::bls12_381::{Fr, FrRepr, G1}; use sha2::{Digest, Sha256}; +type G1 = ArkGroup; + /// This function is an implementation of the procedure described in /// It computes a random scalar in Fr given a seed (the argument `ikm`). /// /// This is a building block for deterministic key generation for identity /// provider, anonymity revoker keys and PRF keys. -pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result { +pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result, hkdf::InvalidLength> { let mut ikm = ikm.to_vec(); ikm.push(0); let l = 48; // = 48 for G1; r is @@ -20,11 +21,12 @@ pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result>::zero(); // shift with // 452312848583266388373324160190187140051835877600158453279131187530910662656 = // 2^248 = 2^(31*8) - let shift = Fr::from_repr(FrRepr([0, 0, 0, 72057594037927936])).unwrap(); + let shift = >::from_repr(&[0, 0, 0, 72057594037927936]).unwrap(); + println!("Shift {:?}", shift); let mut salt = Sha256::digest(&salt[..]); while sk.is_zero() { let (_, h) = Hkdf::::extract(Some(&salt), &ikm); @@ -46,7 +48,9 @@ pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result Result), /// but is still secure. /// This function is needed for backwards compatibility. -pub fn keygen_bls_deprecated(ikm: &[u8], key_info: &[u8]) -> Result { +pub fn keygen_bls_deprecated(ikm: &[u8], key_info: &[u8]) -> Result, hkdf::InvalidLength> { let mut ikm = ikm.to_vec(); ikm.push(0); let l = 48; // = 48 for G1; r is @@ -70,11 +74,11 @@ pub fn keygen_bls_deprecated(ikm: &[u8], key_info: &[u8]) -> Result>::zero(); // shift with // 452312848583266388373324160190187140051835877600158453279131187530910662656 = // 2^248 - let shift = Fr::from_repr(FrRepr([0, 0, 0, 72057594037927936])).unwrap(); + let shift = >::from_repr(&[0, 0, 0, 72057594037927936]).unwrap(); let mut salt = Sha256::digest(&salt[..]); while sk.is_zero() { let (_, h) = Hkdf::::extract(Some(&salt), &ikm); @@ -99,6 +103,7 @@ pub fn keygen_bls_deprecated(ikm: &[u8], key_info: &[u8]) -> Result = sk.into(); + assert_eq!(res.into_repr(), expected_outputs[i]) } else { panic!("Could not generate key from seed.") } From 1b8f8b2aa696e33dfb08c6e8be235d57509e5ef0 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Tue, 12 Dec 2023 22:47:15 +0100 Subject: [PATCH 06/53] Remove Display from Field constraints; custom display for Fr --- .../src/curve_arithmetic/arkworks_instances.rs | 6 ------ .../src/curve_arithmetic/bls12_381_arkworks.rs | 14 +++++++++++++- .../concordium_base/src/curve_arithmetic/mod.rs | 2 +- rust-src/keygen_bls/src/lib.rs | 6 +++--- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 5fc7f4d31..242755506 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -29,12 +29,6 @@ impl Deserial for ArkField { } } -impl fmt::Display for ArkField { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ::fmt(&self.0, f) - } -} - impl Field for ArkField { fn random(rng: &mut R) -> Self { F::rand(rng).into() diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 9e40d2bec..c3a78011a 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -1,3 +1,5 @@ +use core::fmt; + use ark_bls12_381::*; use ark_ec::{ bls12::{G1Prepared, G2Prepared}, @@ -6,7 +8,7 @@ use ark_ec::{ short_weierstrass::Projective, CurveGroup, }; -use ark_ff::{field_hashers::DefaultFieldHasher, BigInt}; +use ark_ff::{field_hashers::DefaultFieldHasher, BigInt, PrimeField}; use sha2::Sha256; use crate::common::{Buffer, Serial}; @@ -110,3 +112,13 @@ impl Pairing for Bls12 { ::rand(csprng).into() } } + +impl fmt::Display for ArkField { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "0x")?; + for i in self.0.into_bigint().0.iter().rev() { + write!(f, "{:016x}", *i)?; + } + Ok(()) + } +} diff --git a/rust-src/concordium_base/src/curve_arithmetic/mod.rs b/rust-src/concordium_base/src/curve_arithmetic/mod.rs index 9e46c57b0..0f350a2dc 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/mod.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/mod.rs @@ -26,7 +26,7 @@ pub enum CurveDecodingError { /// This trait represents an element of a field. pub trait Field: - Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + 'static { + Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + 'static { /// Returns an element chosen uniformly at random using a user-provided RNG. fn random(rng: &mut R) -> Self; diff --git a/rust-src/keygen_bls/src/lib.rs b/rust-src/keygen_bls/src/lib.rs index 4b5339983..6e328d48b 100644 --- a/rust-src/keygen_bls/src/lib.rs +++ b/rust-src/keygen_bls/src/lib.rs @@ -26,7 +26,7 @@ pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result, hkdf::Inv // 452312848583266388373324160190187140051835877600158453279131187530910662656 = // 2^248 = 2^(31*8) let shift = >::from_repr(&[0, 0, 0, 72057594037927936]).unwrap(); - println!("Shift {:?}", shift); + println!("Shift {:}", shift); let mut salt = Sha256::digest(&salt[..]); while sk.is_zero() { let (_, h) = Hkdf::::extract(Some(&salt), &ikm); @@ -48,9 +48,9 @@ pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result, hkdf::Inv let slice_y2 = &mut y2_vec[0..okm.len() - slice_y1.len()]; slice_y2.clone_from_slice(&okm[31..]); let y1 = G1::scalar_from_bytes(y1_vec); - println!("y1 {:?}", y1); + println!("y1 {:}", y1); let mut y2 = G1::scalar_from_bytes(y2_vec); - println!("y2 {:?}", y2); + println!("y2 {:}", y2); y2.mul_assign(&shift); sk = y1; sk.add_assign(&y2); From 7683307bee74114597af6d5c806b4146a7736191 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Wed, 13 Dec 2023 13:11:27 +0100 Subject: [PATCH 07/53] Fixes in serialisation --- .../curve_arithmetic/arkworks_instances.rs | 41 ++++++++++------ .../curve_arithmetic/bls12_381_arkworks.rs | 47 ++++++++++++++++--- .../src/curve_arithmetic/mod.rs | 3 +- rust-src/key_derivation/src/lib.rs | 10 +++- rust-src/keygen_bls/src/lib.rs | 1 + 5 files changed, 78 insertions(+), 24 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 242755506..f1b366ea4 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -1,7 +1,7 @@ use core::fmt; -use std::{str::FromStr}; +use std::str::FromStr; -use crate::common::{Deserial, Serial}; +use crate::common::{Deserial, Serial, Serialize}; use super::{Curve, CurveDecodingError, Field, GenericMultiExp, PrimeField}; use anyhow::anyhow; @@ -14,22 +14,33 @@ impl From for ArkField { fn from(value: F) -> Self { ArkField(value) } } -impl Serial for ArkField { - fn serial(&self, out: &mut B) { - self.0 - .serialize_compressed(out) - .expect("Serialzation expected to succeed") - } +// impl Serial for ArkField { +// fn serial(&self, out: &mut B) { +// self.0 +// .serialize_compressed(out) +// .expect("Serialzation expected to succeed") +// } +// } + +// impl Deserial for ArkField { +// fn deserial(source: &mut R) -> +// crate::common::ParseResult { let res = +// F::deserialize_compressed(source)?; Ok(res.into()) +// } +// } + +impl Serial for ArkField { + fn serial(&self, out: &mut B) { self.0.serial(out) } } -impl Deserial for ArkField { +impl Deserial for ArkField { fn deserial(source: &mut R) -> crate::common::ParseResult { - let res = F::deserialize_compressed(source)?; + let res = F::deserial(source)?; Ok(res.into()) } } -impl Field for ArkField { +impl Field for ArkField { fn random(rng: &mut R) -> Self { F::rand(rng).into() } @@ -59,7 +70,7 @@ impl ArkField { pub fn into_ark(&self) -> &F { &self.0 } } -impl PrimeField for ArkField { +impl PrimeField for ArkField { const CAPACITY: u32 = Self::NUM_BITS - 1; const NUM_BITS: u32 = F::MODULUS_BIT_SIZE; @@ -113,7 +124,10 @@ pub(crate) trait ArkCurveConfig { type Hasher: ark_ec::hashing::HashToCurve; } -impl> Curve for ArkGroup { +impl> Curve for ArkGroup +where + ::ScalarField: Serialize, +{ type MultiExpType = GenericMultiExp; type Scalar = ArkField<::ScalarField>; @@ -175,7 +189,6 @@ impl> Curve for ArkGroup { // fr[3] &= !(1u64 << 63 | 1u64 << 62); ::from_repr(&fr) .expect("The scalar with top two bits erased should be valid.") - } fn hash_to_group(m: &[u8]) -> Self { diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index c3a78011a..77992f49e 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -1,5 +1,6 @@ use core::fmt; +use anyhow::anyhow; use ark_bls12_381::*; use ark_ec::{ bls12::{G1Prepared, G2Prepared}, @@ -9,9 +10,11 @@ use ark_ec::{ CurveGroup, }; use ark_ff::{field_hashers::DefaultFieldHasher, BigInt, PrimeField}; +use byteorder::ReadBytesExt; +use num_bigint::BigUint; use sha2::Sha256; -use crate::common::{Buffer, Serial}; +use crate::common::{Buffer, Deserial, ParseResult, Serial}; use super::{ arkworks_instances::{ArkCurveConfig, ArkField, ArkGroup}, @@ -29,6 +32,7 @@ impl ArkCurveConfig for Projective { const GROUP_ELEMENT_LENGTH: usize = 48; const SCALAR_LENGTH: usize = 32; } + impl ArkCurveConfig for Projective { type Hasher = MapToCurveBasedHasher, WBMap>; @@ -38,6 +42,28 @@ impl ArkCurveConfig for Projective { const SCALAR_LENGTH: usize = 32; } +impl Deserial for Fr { + fn deserial(source: &mut R) -> ParseResult { + let mut buf = [0u8; 32]; + source.read(&mut buf)?; + let big_int: BigInt<4> = BigUint::from_bytes_be(&buf) + .try_into() + .map_err(|_| anyhow!("Cannot convert to bigint"))?; + let res = Fr::from_bigint(big_int) + .ok_or(anyhow!("Cannot convert from bigint to a field element"))?; + Ok(res) + } +} + +impl Serial for Fr { + fn serial(&self, out: &mut B) { + let frpr: BigInt<4> = self.0; + for a in frpr.0.iter().rev() { + a.serial(out); + } + } +} + /// This implementation is ad-hoc, using the fact that Fq12 is defined /// via that specific tower of extensions (of degrees) 2 -> 3 -> 2, /// and the specific representation of those fields. @@ -66,6 +92,13 @@ impl Serial for Fq12 { } } +impl Deserial for Fq12 { + fn deserial(source: &mut R) -> ParseResult { + todo!() + } +} + + type Bls12 = ark_ec::bls12::Bls12; impl Pairing for Bls12 { @@ -115,10 +148,10 @@ impl Pairing for Bls12 { impl fmt::Display for ArkField { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "0x")?; - for i in self.0.into_bigint().0.iter().rev() { - write!(f, "{:016x}", *i)?; - } - Ok(()) - } + write!(f, "0x")?; + for i in self.0.into_bigint().0.iter().rev() { + write!(f, "{:016x}", *i)?; + } + Ok(()) + } } diff --git a/rust-src/concordium_base/src/curve_arithmetic/mod.rs b/rust-src/concordium_base/src/curve_arithmetic/mod.rs index 0f350a2dc..11615df92 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/mod.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/mod.rs @@ -25,8 +25,7 @@ pub enum CurveDecodingError { } /// This trait represents an element of a field. -pub trait Field: - Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + 'static { +pub trait Field: Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + 'static { /// Returns an element chosen uniformly at random using a user-provided RNG. fn random(rng: &mut R) -> Self; diff --git a/rust-src/key_derivation/src/lib.rs b/rust-src/key_derivation/src/lib.rs index adc8a1e72..b2f4eaefe 100644 --- a/rust-src/key_derivation/src/lib.rs +++ b/rust-src/key_derivation/src/lib.rs @@ -9,7 +9,7 @@ use concordium_base::{ }, ps_sig::SigRetrievalRandomness, }; -use ed25519_dalek::{SecretKey, VerifyingKey, SignatureError, SigningKey}; +use ed25519_dalek::{SecretKey, SignatureError, SigningKey, VerifyingKey}; pub use ed25519_hd_key_derivation::DeriveError; use ed25519_hd_key_derivation::{checked_harden, derive_from_parsed_path, harden}; use hmac::Hmac; @@ -221,6 +221,10 @@ impl ConcordiumHdWallet { ])?; let attribute_commitment_randomness_seed = derive_from_parsed_path(&path, &self.seed)?.private_key; + println!( + "attribute_commitment_randomness_seed: {:?}", + attribute_commitment_randomness_seed + ); Ok(CommitmentRandomness::new(bls_key_bytes_from_seed( attribute_commitment_randomness_seed, ))) @@ -532,6 +536,10 @@ mod tests { let attribute_commitment_randomness = create_wallet(Net::Testnet, TEST_SEED_1) .get_attribute_commitment_randomness(5, 0, 4, AttributeTag(0)) .unwrap(); + println!( + "attribute_commitment_randomness: {:?}", + attribute_commitment_randomness + ); assert_eq!( base16_encode_string(&attribute_commitment_randomness), "409fa90314ec8fb4a2ae812fd77fe58bfac81765cad3990478ff7a73ba6d88ae" diff --git a/rust-src/keygen_bls/src/lib.rs b/rust-src/keygen_bls/src/lib.rs index 6e328d48b..5e0b55198 100644 --- a/rust-src/keygen_bls/src/lib.rs +++ b/rust-src/keygen_bls/src/lib.rs @@ -56,6 +56,7 @@ pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result, hkdf::Inv sk.add_assign(&y2); salt = Sha256::digest(salt); } + println!("sk: {:}", sk); Ok(sk) } From 872f53ffa669da404d59b2bda4ef72eabd310a51 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 28 Dec 2023 21:02:28 +0100 Subject: [PATCH 08/53] Fix BLS Fr serialisation; add tests for the arkworks BLS implementation --- rust-src/concordium_base/Cargo.toml | 4 - rust-src/concordium_base/benches/msm_bench.rs | 31 ++-- .../concordium_base/src/aggregate_sig/mod.rs | 2 - .../curve_arithmetic/arkworks_instances.rs | 34 ++-- .../curve_arithmetic/bls12_381_arkworks.rs | 151 ++++++++++++++++-- .../curve_arithmetic/bls12_381_instance.rs | 2 - .../concordium_base/src/id/account_holder.rs | 6 +- rust-src/concordium_base/src/id/constants.rs | 2 +- rust-src/concordium_base/src/web3id/mod.rs | 3 +- rust-src/key_derivation/src/lib.rs | 2 +- rust-src/keygen_bls/src/lib.rs | 3 - 11 files changed, 180 insertions(+), 60 deletions(-) diff --git a/rust-src/concordium_base/Cargo.toml b/rust-src/concordium_base/Cargo.toml index 6c4447b2c..f6e198a5d 100644 --- a/rust-src/concordium_base/Cargo.toml +++ b/rust-src/concordium_base/Cargo.toml @@ -148,10 +148,6 @@ features = ["encryption"] name = "range_proof_bench" harness = false -[[bench]] -name = "range_proof_dalek_bench" -harness = false - [[bench]] name = "msm_bench" harness = false diff --git a/rust-src/concordium_base/benches/msm_bench.rs b/rust-src/concordium_base/benches/msm_bench.rs index a329a9c6e..4a38dce42 100644 --- a/rust-src/concordium_base/benches/msm_bench.rs +++ b/rust-src/concordium_base/benches/msm_bench.rs @@ -38,23 +38,24 @@ pub fn ccd_msm_benchmarks(c: &mut Criterion) { }); } -pub fn dalek_msm_benchmarks(c: &mut Criterion) { - let mut group = c.benchmark_group("Multi-Scalar Multiplication"); - let mut rng = &mut thread_rng(); - - use curve25519_dalek_ng::{scalar::Scalar, traits::VartimeMultiscalarMul}; - let G: Vec = (0..N).map(|_| RistrettoPoint::random(&mut rng)).collect(); - let V: Vec<_> = (0..N).map(|_| Scalar::random(&mut rng)).collect(); - - group.bench_function("MSM in Dalek over Ristretto curve", move |b| { - b.iter(|| { - RistrettoPoint::vartime_multiscalar_mul(&V, &G); - }) - }); -} +// pub fn dalek_msm_benchmarks(c: &mut Criterion) { +// let mut group = c.benchmark_group("Multi-Scalar Multiplication"); +// let mut rng = &mut thread_rng(); + +// use curve25519_dalek_ng::{scalar::Scalar, traits::VartimeMultiscalarMul}; +// let G: Vec = (0..N).map(|_| RistrettoPoint::random(&mut +// rng)).collect(); let V: Vec<_> = (0..N).map(|_| Scalar::random(&mut +// rng)).collect(); + +// group.bench_function("MSM in Dalek over Ristretto curve", move |b| { +// b.iter(|| { +// RistrettoPoint::vartime_multiscalar_mul(&V, &G); +// }) +// }); +// } criterion_group!( name = benchmarks; config = Criterion::default().measurement_time(Duration::from_millis(10000)).sample_size(100); - targets = ccd_msm_benchmarks::, ccd_msm_benchmarks::, dalek_msm_benchmarks); + targets = ccd_msm_benchmarks::, ccd_msm_benchmarks::); criterion_main!(benchmarks); diff --git a/rust-src/concordium_base/src/aggregate_sig/mod.rs b/rust-src/concordium_base/src/aggregate_sig/mod.rs index d2133a889..a965dec1a 100644 --- a/rust-src/concordium_base/src/aggregate_sig/mod.rs +++ b/rust-src/concordium_base/src/aggregate_sig/mod.rs @@ -280,8 +280,6 @@ fn hash_message(m: &[u8]) -> Output { Sha512::digest(m) } #[cfg(test)] mod test { - use crate::curve_arithmetic::arkworks_instances::ArkGroup; - use super::*; use rand::{rngs::StdRng, thread_rng, SeedableRng}; use std::convert::TryFrom; diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index f1b366ea4..b15fee625 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -5,7 +5,8 @@ use crate::common::{Deserial, Serial, Serialize}; use super::{Curve, CurveDecodingError, Field, GenericMultiExp, PrimeField}; use anyhow::anyhow; -use ark_ec::{hashing::HashToCurve, AffineRepr}; +use ark_ec::hashing::HashToCurve; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; #[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, fmt::Debug)] pub struct ArkField(pub(crate) F); @@ -29,18 +30,18 @@ impl From for ArkField { // } // } -impl Serial for ArkField { +impl Serial for ArkField { fn serial(&self, out: &mut B) { self.0.serial(out) } } -impl Deserial for ArkField { +impl Deserial for ArkField { fn deserial(source: &mut R) -> crate::common::ParseResult { let res = F::deserial(source)?; Ok(res.into()) } } -impl Field for ArkField { +impl Field for ArkField { fn random(rng: &mut R) -> Self { F::rand(rng).into() } @@ -78,6 +79,7 @@ impl PrimeField for ArkField { fn from_repr(repr: &[u64]) -> Result { let mut buffer = Vec::with_capacity(8 * repr.len()); + for u in repr { buffer.extend(u.to_le_bytes()); } @@ -85,8 +87,10 @@ impl PrimeField for ArkField { let big_int = num_bigint::BigUint::from_bytes_le(&buffer) .try_into() .map_err(|_| CurveDecodingError::NotInField(format!("{:?}", repr)))?; + let res = F::from_bigint(big_int).ok_or(CurveDecodingError::NotInField(format!("{:?}", repr)))?; + Ok(res.into()) } } @@ -101,15 +105,16 @@ impl ArkGroup { impl Serial for ArkGroup { fn serial(&self, out: &mut B) { self.0 + .into_affine() .serialize_compressed(out) - .expect("Serialzation expected to succeed") + .expect("Serialzation expected to succeed"); } } impl Deserial for ArkGroup { fn deserial(source: &mut R) -> crate::common::ParseResult { - let res = G::deserialize_compressed(source)?; - Ok(ArkGroup(res)) + let res = G::Affine::deserialize_compressed(source)?; + Ok(ArkGroup(res.into())) } } @@ -151,14 +156,10 @@ where fn mul_by_scalar(&self, scalar: &Self::Scalar) -> Self { ArkGroup(self.0 * scalar.0) } fn bytes_to_curve_unchecked(b: &mut R) -> anyhow::Result { - // TODO: this implementation is not efficient. - let mut buffer = Vec::new(); - b.read(&mut buffer)?; - // In fact, `from_random_bytes` checks if the bytes correspond to a valid group - // element. It seems like there is no unchecked methods exposed through - // ark traits. - let res = G::Affine::from_random_bytes(&buffer) - .ok_or(anyhow!("Expected a valid group element"))?; + // TODO: this is not the most efficient implementation, since there might be + // some additional checks durind deserialization. However, it seems + // there are no unchecked methods available through traits. + let res = G::Affine::deserialize_compressed(b).map_err(|e| anyhow!(e))?; Ok(ArkGroup(res.into())) } @@ -174,9 +175,6 @@ where // Traverse at most 4 8-byte chunks, for a total of 256 bits. // The top-most two bits in the last chunk are set to 0. let s = num::integer::div_ceil(Self::Scalar::CAPACITY, 8); - println!("{:?}", Self::Scalar::NUM_BITS); - println!("{:?}", Self::Scalar::CAPACITY); - println!("{:?}", s); let mut fr = Vec::with_capacity(s as usize); for chunk in bs.as_ref().chunks(8).take(s as usize) { let mut v = [0u8; 8]; diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 77992f49e..d2ae27ca9 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -1,6 +1,5 @@ use core::fmt; -use anyhow::anyhow; use ark_bls12_381::*; use ark_ec::{ bls12::{G1Prepared, G2Prepared}, @@ -16,6 +15,8 @@ use sha2::Sha256; use crate::common::{Buffer, Deserial, ParseResult, Serial}; +use anyhow::anyhow; + use super::{ arkworks_instances::{ArkCurveConfig, ArkField, ArkGroup}, Pairing, @@ -46,6 +47,7 @@ impl Deserial for Fr { fn deserial(source: &mut R) -> ParseResult { let mut buf = [0u8; 32]; source.read(&mut buf)?; + // Construct the scalar from big endian bytes. let big_int: BigInt<4> = BigUint::from_bytes_be(&buf) .try_into() .map_err(|_| anyhow!("Cannot convert to bigint"))?; @@ -57,7 +59,10 @@ impl Deserial for Fr { impl Serial for Fr { fn serial(&self, out: &mut B) { - let frpr: BigInt<4> = self.0; + // Note that it is crucial to use `into_bigint()` here. + // The internal representation is accessible direclty, but it's NOT the same + // (it's a Montgomery representation optimized for modular arithmetic) + let frpr = self.into_bigint(); for a in frpr.0.iter().rev() { a.serial(out); } @@ -92,13 +97,6 @@ impl Serial for Fq12 { } } -impl Deserial for Fq12 { - fn deserial(source: &mut R) -> ParseResult { - todo!() - } -} - - type Bls12 = ark_ec::bls12::Bls12; impl Pairing for Bls12 { @@ -155,3 +153,138 @@ impl fmt::Display for ArkField { Ok(()) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + common::*, + curve_arithmetic::{Curve, Field, PrimeField}, + }; + use num_bigint::BigUint; + use rand::thread_rng; + use std::io::Cursor; + + const SCALAR_BYTES_LE: [u8; 32] = [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 0, + 0, 0, 0, 0, 0, 0, 0, + ]; + + // Check that scalar_from_bytes_helper works on small values. + #[test] + fn scalar_from_bytes_small() { + let mut rng = rand::thread_rng(); + for _ in 0..1000 { + let n = >::random(&mut rng); + let mut bytes = to_bytes(&n); + bytes.reverse(); + let m = as Curve>::scalar_from_bytes(&bytes); + // make sure that n and m only differ in the topmost bit. + let n = n.into_repr(); + let m = m.into_repr(); + let mask = !(1u64 << 63 | 1u64 << 62); + assert_eq!(n[0], m[0], "First limb."); + assert_eq!(n[1], m[1], "Second limb."); + assert_eq!(n[2], m[2], "Third limb."); + assert_eq!(n[3] & mask, m[3] & mask, "Fourth limb with top bit masked."); + } + } + + /// Test that `into_repr()` correclty converts a scalar constructed from a + /// byte array to an array of limbs with least significant digits first. + #[test] + fn test_into() { + let bigint: BigUint = BigUint::from_bytes_le(&SCALAR_BYTES_LE); + let s: ArkField = Fr::try_from(bigint) + .expect("Expected a valid scalar") + .into(); + assert_eq!(s.into_repr(), [1u64, 0u64, u64::MAX - 1, 0u64]); + } + + /// Turn scalar elements into representations and back again, and compare. + #[test] + fn test_into_from_rep() { + let mut csprng = rand::thread_rng(); + for _ in 0..1000 { + let scalar = >::random(&mut csprng); + let scalar_vec64 = scalar.into_repr(); + let scalar_res = >::from_repr(&scalar_vec64); + assert!(scalar_res.is_ok()); + assert_eq!(scalar, scalar_res.unwrap()); + } + } + + #[test] + fn test_scalar_serialize_big_endian() { + let bigint: BigUint = BigUint::from_bytes_le(&SCALAR_BYTES_LE); + let b: BigInt<4> = bigint + .try_into() + .expect("Expeted valid biguint representing a fired element"); + let s: ArkField = ::from_bigint(b) + .expect("Expected a valid scalar") + .into(); + let mut out = Vec::new(); + s.serial(&mut out); + let scalar_bytes_be: Vec = SCALAR_BYTES_LE.into_iter().rev().collect(); + assert_eq!(scalar_bytes_be, out); + } + + macro_rules! macro_test_scalar_byte_conversion { + ($function_name:ident, $p:path) => { + #[test] + pub fn $function_name() { + let mut csprng = thread_rng(); + for _ in 0..1000 { + let scalar = <$p>::generate_scalar(&mut csprng); + let scalar_res = serialize_deserialize(&scalar); + assert!(scalar_res.is_ok()); + assert_eq!(scalar, scalar_res.unwrap()); + } + } + }; + } + + macro_rules! macro_test_group_byte_conversion { + ($function_name:ident, $p:path) => { + #[test] + pub fn $function_name() { + let mut csprng = thread_rng(); + for _ in 0..1000 { + let curve = <$p>::generate(&mut csprng); + let curve_res = serialize_deserialize(&curve); + assert!(curve_res.is_ok()); + assert_eq!(curve, curve_res.unwrap()); + } + } + }; + } + + macro_rules! macro_test_group_byte_conversion_unchecked { + ($function_name:ident, $p:path) => { + #[test] + pub fn $function_name() { + let mut csprng = thread_rng(); + for _ in 0..1000 { + let curve = <$p>::generate(&mut csprng); + let bytes = to_bytes(&curve); + let curve_res = <$p>::bytes_to_curve_unchecked(&mut Cursor::new(&bytes)); + assert!(curve_res.is_ok()); + assert_eq!(curve, curve_res.unwrap()); + } + } + }; + } + + type G1 = ArkGroup; + type G2 = ArkGroup; + + macro_test_scalar_byte_conversion!(sc_bytes_conv_g1, G1); + macro_test_scalar_byte_conversion!(sc_bytes_conv_g2, G2); + macro_test_scalar_byte_conversion!(sc_bytes_conv_bls12, Bls12); + + macro_test_group_byte_conversion!(curve_bytes_conv_g1, G1); + macro_test_group_byte_conversion!(curve_bytes_conv_g2, G2); + + macro_test_group_byte_conversion_unchecked!(u_curve_bytes_conv_g1, G1); + macro_test_group_byte_conversion_unchecked!(u_curve_bytes_conv_g2, G2); +} diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_instance.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_instance.rs index 99d631410..17bfdf960 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_instance.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_instance.rs @@ -51,8 +51,6 @@ impl Field for F { fn mul_assign(&mut self, other: &Self) { self.mul_assign(other) } fn inverse(&self) -> Option { self.inverse() } - - // fn frobenius_map(&mut self, power: usize) { self.frobenius_map(power) } } impl From for CurveDecodingError { diff --git a/rust-src/concordium_base/src/id/account_holder.rs b/rust-src/concordium_base/src/id/account_holder.rs index c799fe8f3..2ba7f2a82 100644 --- a/rust-src/concordium_base/src/id/account_holder.rs +++ b/rust-src/concordium_base/src/id/account_holder.rs @@ -1261,17 +1261,17 @@ mod tests { use crate::{ common::types::{KeyIndex, KeyPair}, curve_arithmetic::{ - arkworks_instances::{ArkField, ArkGroup}, + arkworks_instances::ArkGroup, Curve, }, id::{constants::*, identity_provider::*, secret_sharing::Threshold, test::*}, pedersen_commitment::CommitmentKey as PedersenKey, }; - use ark_bls12_381::{g1, Fr, G1Projective}; + use ark_bls12_381::g1; use ark_ec::short_weierstrass::Projective; use either::Either::Left; - type ExampleCurve = ArkGroup>; // ArkGroup; + type ExampleCurve = ArkGroup>; const EXPIRY: TransactionTime = TransactionTime { seconds: 111111111111111111, diff --git a/rust-src/concordium_base/src/id/constants.rs b/rust-src/concordium_base/src/id/constants.rs index aaeee1eda..a6356f0f0 100644 --- a/rust-src/concordium_base/src/id/constants.rs +++ b/rust-src/concordium_base/src/id/constants.rs @@ -7,7 +7,7 @@ use crate::{ Serial, }, curve_arithmetic::{ - arkworks_instances::{ArkField, ArkGroup}, + arkworks_instances::ArkGroup, Curve, Pairing, }, }; diff --git a/rust-src/concordium_base/src/web3id/mod.rs b/rust-src/concordium_base/src/web3id/mod.rs index faf74a192..3be1f16f7 100644 --- a/rust-src/concordium_base/src/web3id/mod.rs +++ b/rust-src/concordium_base/src/web3id/mod.rs @@ -682,7 +682,7 @@ impl TryFrom<&str> for Ed25519PublicKey { type Error = Ed25519PublicKeyFromStrError; fn try_from(value: &str) -> Result { - let bytes: [u8; 32] = hex::decode(value)?.try_into().map_err(|e| { + let bytes: [u8; 32] = hex::decode(value)?.try_into().map_err(|_| { Self::Error::InvalidBytes(ed25519_dalek::SignatureError::from_source( "Incorrect public key length.", )) @@ -1785,7 +1785,6 @@ mod tests { }; use anyhow::Context; use chrono::TimeZone; - use ed25519_dalek::ed25519::signature::Keypair; use rand::Rng; use std::marker::PhantomData; diff --git a/rust-src/key_derivation/src/lib.rs b/rust-src/key_derivation/src/lib.rs index b2f4eaefe..beb2c0076 100644 --- a/rust-src/key_derivation/src/lib.rs +++ b/rust-src/key_derivation/src/lib.rs @@ -9,7 +9,7 @@ use concordium_base::{ }, ps_sig::SigRetrievalRandomness, }; -use ed25519_dalek::{SecretKey, SignatureError, SigningKey, VerifyingKey}; +use ed25519_dalek::{SecretKey, SigningKey, VerifyingKey}; pub use ed25519_hd_key_derivation::DeriveError; use ed25519_hd_key_derivation::{checked_harden, derive_from_parsed_path, harden}; use hmac::Hmac; diff --git a/rust-src/keygen_bls/src/lib.rs b/rust-src/keygen_bls/src/lib.rs index 5e0b55198..cb33a7e6a 100644 --- a/rust-src/keygen_bls/src/lib.rs +++ b/rust-src/keygen_bls/src/lib.rs @@ -48,15 +48,12 @@ pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result, hkdf::Inv let slice_y2 = &mut y2_vec[0..okm.len() - slice_y1.len()]; slice_y2.clone_from_slice(&okm[31..]); let y1 = G1::scalar_from_bytes(y1_vec); - println!("y1 {:}", y1); let mut y2 = G1::scalar_from_bytes(y2_vec); - println!("y2 {:}", y2); y2.mul_assign(&shift); sk = y1; sk.add_assign(&y2); salt = Sha256::digest(salt); } - println!("sk: {:}", sk); Ok(sk) } From 7e56b55a403d615824ae12a3f2e3411fb9cb8030 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Tue, 2 Jan 2024 17:00:56 +0100 Subject: [PATCH 09/53] Update the rest of the code to work with v2 of de25519-dalek; remove public key from parameters where it's suficient to pass a secret key (e.g. signing) --- .../Concordium/Crypto/Ed25519Signature.hs | 2 +- identity-provider-service/src/bin/main.rs | 16 ++-- idiss/Cargo.lock | 56 +++---------- idiss/Cargo.toml | 4 +- idiss/src/lib.rs | 7 +- mobile_wallet/Cargo.lock | 6 +- mobile_wallet/Cargo.toml | 6 +- mobile_wallet/src/lib.rs | 9 ++- rust-bins/Cargo.lock | 25 ++---- rust-bins/Cargo.toml | 9 ++- rust-bins/src/bin/client.rs | 18 +++-- rust-bins/src/bin/generate_testdata.rs | 12 ++- rust-bins/src/bin/identity_provider_cli.rs | 3 +- rust-bins/src/bin/keygen-genesis.rs | 12 ++- rust-bins/src/bin/keygen.rs | 25 +++--- rust-bins/src/bin/user_cli.rs | 4 +- rust-bins/src/lib.rs | 3 +- .../benches/range_proof_dalek_bench.rs | 57 ------------- .../src/eddsa_ed25519/dlog_ed25519.rs | 9 +-- .../concordium_base/src/eddsa_ed25519/ffi.rs | 80 ++++++++++++------- .../concordium_base/src/id/account_holder.rs | 5 +- rust-src/concordium_base/src/id/constants.rs | 5 +- .../src/id/identity_provider.rs | 9 +-- rust-src/concordium_base/src/id/test.rs | 5 +- rust-src/ed25519_hd_key_derivation/src/lib.rs | 1 - 25 files changed, 156 insertions(+), 232 deletions(-) delete mode 100644 rust-src/concordium_base/benches/range_proof_dalek_bench.rs diff --git a/haskell-src/Concordium/Crypto/Ed25519Signature.hs b/haskell-src/Concordium/Crypto/Ed25519Signature.hs index 104e9d969..bd6b05b47 100644 --- a/haskell-src/Concordium/Crypto/Ed25519Signature.hs +++ b/haskell-src/Concordium/Crypto/Ed25519Signature.hs @@ -25,7 +25,7 @@ import System.IO.Unsafe foreign import ccall unsafe "eddsa_priv_key" genPrivateKey :: IO (Ptr SignKey) foreign import ccall unsafe "eddsa_pub_key" derivePublicFFI :: Ptr SignKey -> IO (Ptr VerifyKey) -foreign import ccall unsafe "eddsa_sign" signFFI :: Ptr Word8 -> Word32 -> Ptr SignKey -> Ptr VerifyKey -> Ptr Word8 -> IO () +foreign import ccall unsafe "eddsa_sign" signFFI :: Ptr Word8 -> Word32 -> Ptr SignKey -> Ptr Word8 -> IO () foreign import ccall unsafe "eddsa_verify" verifyFFI :: Ptr Word8 -> Word32 -> Ptr VerifyKey -> Ptr Word8 -> CSize -> IO Int32 foreign import ccall unsafe "&eddsa_public_free" freeVerifyKey :: FunPtr (Ptr VerifyKey -> IO ()) foreign import ccall unsafe "eddsa_public_to_bytes" toBytesVerifyKey :: Ptr VerifyKey -> Ptr CSize -> IO (Ptr Word8) diff --git a/identity-provider-service/src/bin/main.rs b/identity-provider-service/src/bin/main.rs index ccf9e3f5e..46bed442d 100644 --- a/identity-provider-service/src/bin/main.rs +++ b/identity-provider-service/src/bin/main.rs @@ -15,7 +15,7 @@ use concordium_base::{ types::*, }, }; -//use ed25519_dalek::{ExpandedSecretKey, PublicKey}; +use ed25519_dalek::{SigningKey, Signer}; use log::{error, info, warn}; use reqwest::Client; use serde_json::{from_str, json, to_value}; @@ -962,11 +962,10 @@ async fn save_validated_request( // Sign the id_cred_pub so that the identity verifier can verify that the given // id_cred_pub matches a valid identity creation request. - let public_key: PublicKey = server_config.ip_data.public_ip_info.ip_cdi_verify_key; - let expanded_secret_key: ExpandedSecretKey = - ExpandedSecretKey::from(&server_config.ip_data.ip_cdi_secret_key); + let expanded_secret_key = + SigningKey::from(&server_config.ip_data.ip_cdi_secret_key); let signature_on_id_cred_pub = - expanded_secret_key.sign(id_cred_pub_hash.as_slice(), &public_key); + expanded_secret_key.sign(id_cred_pub_hash.as_slice()); let serialized_signature = base16_encode_string(&signature_on_id_cred_pub); ok_or_500!( @@ -1000,11 +999,10 @@ async fn save_validated_request_v1( // Sign the id_cred_pub so that the identity verifier can verify that the given // id_cred_pub matches a valid identity creation request. - let public_key: PublicKey = server_config.ip_data.public_ip_info.ip_cdi_verify_key; - let expanded_secret_key: ExpandedSecretKey = - ExpandedSecretKey::from(&server_config.ip_data.ip_cdi_secret_key); + let expanded_secret_key: SigningKey = + SigningKey::from(&server_config.ip_data.ip_cdi_secret_key); let signature_on_id_cred_pub = - expanded_secret_key.sign(id_cred_pub_hash.as_slice(), &public_key); + expanded_secret_key.sign(id_cred_pub_hash.as_slice()); let serialized_signature = base16_encode_string(&signature_on_id_cred_pub); ok_or_500!( diff --git a/idiss/Cargo.lock b/idiss/Cargo.lock index 372eb0345..33379d811 100644 --- a/idiss/Cargo.lock +++ b/idiss/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ "derivative", "digest 0.10.7", "itertools", - "num-bigint 0.4.4", + "num-bigint", "num-traits", "paste", "rustc_version", @@ -128,7 +128,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint 0.4.4", + "num-bigint", "num-traits", "proc-macro2", "quote", @@ -157,7 +157,7 @@ dependencies = [ "ark-serialize-derive", "ark-std", "digest 0.10.7", - "num-bigint 0.4.4", + "num-bigint", ] [[package]] @@ -481,7 +481,7 @@ dependencies = [ "fnv", "hashbrown 0.11.2", "hex", - "num-bigint 0.4.4", + "num-bigint", "num-integer", "num-traits", "rust_decimal", @@ -529,7 +529,7 @@ dependencies = [ "merlin", "nom 7.1.3", "num", - "num-bigint 0.4.4", + "num-bigint", "num-traits", "rand 0.8.5", "rayon", @@ -821,24 +821,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4530da57967e140ee0b44e0143aa66b5cb42bd9c503dbe316a15d5b0be65713e" dependencies = [ "byteorder", - "ff_derive", "rand_core 0.5.1", ] -[[package]] -name = "ff_derive" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5796e7d62ca01a00ed3a649b0da1ffa1ac8f06bcad40339df09dbdd69a05ba9" -dependencies = [ - "num-bigint 0.2.6", - "num-integer", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "fiat-crypto" version = "0.2.5" @@ -991,15 +976,15 @@ name = "idiss" version = "0.7.0" dependencies = [ "anyhow", + "ark-bls12-381", + "ark-ec", "byteorder", "chrono", "concordium_base", "ed25519-dalek", - "ff", "hex", "napi-build", "nodejs-sys", - "pairing", "serde", "serde_json", ] @@ -1173,7 +1158,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" dependencies = [ - "num-bigint 0.4.4", + "num-bigint", "num-complex", "num-integer", "num-iter", @@ -1181,17 +1166,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-bigint" version = "0.4.4" @@ -1240,7 +1214,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", - "num-bigint 0.4.4", + "num-bigint", "num-integer", "num-traits", ] @@ -1266,18 +1240,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "pairing" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c40534479a28199cd5109da27fe2fc4a4728e4fc701d9e9c1bded78f3271e4" -dependencies = [ - "byteorder", - "ff", - "group", - "rand_core 0.5.1", -] - [[package]] name = "paste" version = "1.0.14" diff --git a/idiss/Cargo.toml b/idiss/Cargo.toml index 0cd9b0845..2bf676c3b 100644 --- a/idiss/Cargo.toml +++ b/idiss/Cargo.toml @@ -26,14 +26,14 @@ csharp = [] [dependencies] anyhow = "1.0" -pairing = "0.15" -ff = "0.5" hex = "0.4" serde = "1.0" serde_json = "1.0" chrono = "0.4.24" # the patch version is necessary since chrono adds new functionality in patch versions ed25519-dalek = "2.0" byteorder = "1.3" +ark-bls12-381 = { version = "0.4"} +ark-ec = { version = "0.4"} [dependencies.nodejs-sys] version = "0.12.0" diff --git a/idiss/src/lib.rs b/idiss/src/lib.rs index 37a1a10ba..5528a6ff0 100644 --- a/idiss/src/lib.rs +++ b/idiss/src/lib.rs @@ -1,7 +1,8 @@ use anyhow::Context; +use ark_bls12_381::G1Projective; use concordium_base::{ common::{base16_decode_string, types::TransactionTime, Versioned, VERSION_0}, - curve_arithmetic::*, + curve_arithmetic::{*, arkworks_instances::ArkGroup}, id, id::{ constants::{ArCurve, AttributeKind}, @@ -14,11 +15,13 @@ use concordium_base::{ }, ps_sig, }; -use pairing::bls12_381::{Bls12, G1}; use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize}; #[cfg(feature = "nodejs")] use serde_json::ser::to_string; +type Bls12 = ark_ec::bls12::Bls12; +type G1 = ArkGroup; + type ExampleCurve = G1; type ExampleAttributeList = AttributeList<::ScalarField, AttributeKind>; diff --git a/mobile_wallet/Cargo.lock b/mobile_wallet/Cargo.lock index ce08b3a2d..1120375e3 100644 --- a/mobile_wallet/Cargo.lock +++ b/mobile_wallet/Cargo.lock @@ -1120,6 +1120,8 @@ name = "mobile_wallet" version = "0.25.0" dependencies = [ "anyhow", + "ark-bls12-381", + "ark-ec", "base64", "byteorder", "chrono", @@ -1127,13 +1129,11 @@ dependencies = [ "ed25519-dalek", "ed25519_hd_key_derivation", "either", - "ff", "hex", "jni", "key_derivation", "libc", - "pairing", - "rand 0.7.3", + "rand 0.8.5", "serde", "serde_json", "sha2 0.10.6", diff --git a/mobile_wallet/Cargo.toml b/mobile_wallet/Cargo.toml index 72c10eb46..15a5ed7e6 100644 --- a/mobile_wallet/Cargo.toml +++ b/mobile_wallet/Cargo.toml @@ -8,9 +8,7 @@ license-file = "../../LICENSE-APACHE" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -pairing = "0.15" -ff = "0.5" -rand = "=0.7" +rand = "=0.8" hex = "0.4" serde = "1.0" serde_json = "1.0" @@ -23,6 +21,8 @@ sha2 = "0.10" libc = "0.2" thiserror = "1.0" base64 = "0.21" +ark-bls12-381 = { version = "0.4"} +ark-ec = { version = "0.4"} [dependencies.key_derivation] path = "../rust-src/key_derivation" diff --git a/mobile_wallet/src/lib.rs b/mobile_wallet/src/lib.rs index 753580a0a..b03df6fd6 100644 --- a/mobile_wallet/src/lib.rs +++ b/mobile_wallet/src/lib.rs @@ -34,7 +34,6 @@ use concordium_base::{ use either::Either::{Left, Right}; use key_derivation::{ConcordiumHdWallet, CredentialContext, Net}; use libc::c_char; -use pairing::bls12_381::Bls12; use rand::thread_rng; use serde_json::{from_str, from_value, to_string, Value}; use sha2::{Digest, Sha256}; @@ -46,6 +45,8 @@ use std::{ str::FromStr, }; +type Bls12 = ark_ec::bls12::Bls12; + /// Context for a transaction to send. #[derive(common::SerdeDeserialize)] #[serde(rename_all = "camelCase")] @@ -659,7 +660,7 @@ fn create_id_request_and_private_data_aux(input: &str) -> anyhow::Result let mut csprng = thread_rng(); keys.insert( KeyIndex(0), - concordium_base::common::types::KeyPair::from(ed25519_dalek::Keypair::generate( + concordium_base::common::types::KeyPair::from(ed25519_dalek::SigningKey::generate( &mut csprng, )), ); @@ -919,8 +920,8 @@ fn create_credential_v1_aux(input: &str) -> anyhow::Result { identity_index, u32::from(acc_num), )?; - let public = ed25519_dalek::PublicKey::from(&secret); - keys.insert(KeyIndex(0), KeyPair { secret, public }); + let signing_key = ed25519_dalek::SigningKey::from(&secret); + keys.insert(KeyIndex(0), signing_key.into()); CredentialData { keys, diff --git a/rust-bins/Cargo.lock b/rust-bins/Cargo.lock index 12e1ca0dc..f2f8644bf 100644 --- a/rust-bins/Cargo.lock +++ b/rust-bins/Cargo.lock @@ -550,7 +550,7 @@ dependencies = [ "chrono", "concordium-contracts-common", "concordium_base_derive", - "curve25519-dalek 4.1.1", + "curve25519-dalek", "curve25519-dalek-ng", "derive_more", "ed25519-dalek", @@ -709,19 +709,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - [[package]] name = "curve25519-dalek" version = "4.1.1" @@ -882,6 +869,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" dependencies = [ "pkcs8", + "serde", "signature", ] @@ -891,7 +879,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek 4.1.1", + "curve25519-dalek", "ed25519", "rand_core 0.6.4", "serde", @@ -1570,13 +1558,15 @@ version = "2.0.1" dependencies = [ "aes", "anyhow", + "ark-bls12-381", + "ark-ec", "base64", "bitvec", "chrono", "clap", "concordium_base", "crossterm", - "curve25519-dalek 3.2.0", + "curve25519-dalek", "dialoguer", "ed25519-dalek", "ed25519_hd_key_derivation", @@ -1588,9 +1578,8 @@ dependencies = [ "key_derivation", "keygen_bls", "openssl-sys", - "pairing", "pbkdf2 0.11.0", - "rand 0.7.3", + "rand 0.8.5", "reqwest", "rpassword", "serde", diff --git a/rust-bins/Cargo.toml b/rust-bins/Cargo.toml index 4b1149f68..45cef0810 100644 --- a/rust-bins/Cargo.toml +++ b/rust-bins/Cargo.toml @@ -13,12 +13,11 @@ vendored-ssl = ["openssl-sys/vendored"] [dependencies] clap = "2.33" dialoguer = "0.10" -pairing = "0.15" -rand = "=0.7" +rand = "=0.8" serde = "1.0" serde_json = "1.0" -ed25519-dalek = "2.0" -curve25519-dalek = "3.0" +ed25519-dalek = { version = "2.0", features = ["serde"]} +curve25519-dalek = "4.0" structopt = "0.3" hex = "0.4" sha2 = "0.10" @@ -37,6 +36,8 @@ rpassword = "6.0" bitvec = "1" crossterm = "0.22" anyhow = "1.0" +ark-bls12-381 = { version = "0.4"} +ark-ec = { version = "0.4"} [dependencies.ed25519_hd_key_derivation] path = "../rust-src/ed25519_hd_key_derivation" diff --git a/rust-bins/src/bin/client.rs b/rust-bins/src/bin/client.rs index 4d7383d6f..2dc62d8df 100644 --- a/rust-bins/src/bin/client.rs +++ b/rust-bins/src/bin/client.rs @@ -1,3 +1,4 @@ +use ark_bls12_381::G1Projective; use clap::AppSettings; use client_server_helpers::*; use concordium_base::{ @@ -17,13 +18,12 @@ use concordium_base::{ types::*, }, pedersen_commitment::Value as PedersenValue, - ps_sig, + ps_sig, curve_arithmetic::arkworks_instances::ArkGroup, }; use dialoguer::{Input, MultiSelect, Select}; use ed25519_dalek as ed25519; use either::Either::{Left, Right}; use key_derivation::{words_to_seed, ConcordiumHdWallet, CredentialContext, Net}; -use pairing::bls12_381::{Bls12, G1}; use rand::*; use serde_json::{json, to_value}; use std::{ @@ -36,6 +36,9 @@ use std::{ }; use structopt::StructOpt; +type Bls12 = ark_ec::bls12::Bls12; +type G1 = ArkGroup; + static IP_NAME_PREFIX: &str = "identity_provider-"; static AR_NAME_PREFIX: &str = "AR-"; @@ -1144,8 +1147,8 @@ fn handle_create_credential(cc: CreateCredential) { }; let cred_data = { let mut keys = std::collections::BTreeMap::new(); - let public = ed25519::VerifyingKey::from(&secret); - keys.insert(KeyIndex(0), KeyPair { secret, public }); + let signing_key = ed25519::SigningKey::from(&secret); + keys.insert(KeyIndex(0), signing_key.into()); CredentialData { keys, @@ -2217,9 +2220,10 @@ fn handle_generate_ips(gip: GenerateIps) { let id_secret_key = ps_sig::SecretKey::::generate(gip.key_capacity, &mut csprng); let id_public_key = ps_sig::PublicKey::from(&id_secret_key); - let keypair = ed25519::Keypair::generate(&mut csprng); - let ip_cdi_verify_key = keypair.public; - let ip_cdi_secret_key = keypair.secret; + let signing_key = ed25519::SigningKey::generate(&mut csprng); + let secret_key = signing_key.to_bytes(); + let ip_cdi_verify_key = signing_key.verifying_key(); + let ip_cdi_secret_key = secret_key; let ip_id = IpIdentity(id as u32); let ip_info = IpInfo { diff --git a/rust-bins/src/bin/generate_testdata.rs b/rust-bins/src/bin/generate_testdata.rs index d51653323..7f60bbd97 100644 --- a/rust-bins/src/bin/generate_testdata.rs +++ b/rust-bins/src/bin/generate_testdata.rs @@ -1,3 +1,4 @@ +use ark_bls12_381::G1Projective; use clap::AppSettings; use client_server_helpers::*; use concordium_base::{ @@ -5,7 +6,7 @@ use concordium_base::{ types::{KeyIndex, KeyPair, TransactionTime}, *, }, - curve_arithmetic::{Curve, Pairing}, + curve_arithmetic::{Curve, Pairing, arkworks_instances::ArkGroup}, dodis_yampolskiy_prf as prf, id::{ account_holder::*, @@ -17,11 +18,13 @@ use concordium_base::{ ps_sig, }; use either::{Left, Right}; -use pairing::bls12_381::{Bls12, G1}; use rand::*; use std::{collections::btree_map::BTreeMap, fs::File, io::Write, path::PathBuf}; use structopt::StructOpt; +type Bls12 = ark_ec::bls12::Bls12; +type G1 = ArkGroup; + type ExampleAttribute = AttributeKind; type ExampleAttributeList = AttributeList<::ScalarField, ExampleAttribute>; @@ -478,6 +481,7 @@ fn main() { generate_initial(prf_key, 2, &ip_cdi_secret_key); generate_initial(prf_key_same, 3, &ip_cdi_secret_key); // Reuse of prf key let prf_key: prf::SecretKey = prf::SecretKey::generate(&mut csprng); - let wrong_keys = ed25519_dalek::Keypair::generate(&mut csprng); - generate_initial(prf_key, 4, &wrong_keys.secret); // Wrong secret key + let mut wrong_keys = ed25519_dalek::SecretKey::default(); + csprng.fill_bytes(&mut wrong_keys); + generate_initial(prf_key, 4, &wrong_keys); // Wrong secret key } diff --git a/rust-bins/src/bin/identity_provider_cli.rs b/rust-bins/src/bin/identity_provider_cli.rs index d270c6294..b5798661a 100644 --- a/rust-bins/src/bin/identity_provider_cli.rs +++ b/rust-bins/src/bin/identity_provider_cli.rs @@ -11,10 +11,11 @@ use concordium_base::{ }, }; use dialoguer::Input; -use pairing::bls12_381::Bls12; use std::{collections::btree_map::BTreeMap, path::PathBuf}; use structopt::StructOpt; +type Bls12 = ark_ec::bls12::Bls12; + #[derive(StructOpt)] #[structopt( about = "Command line client that supports issuing identities for enterprises.", diff --git a/rust-bins/src/bin/keygen-genesis.rs b/rust-bins/src/bin/keygen-genesis.rs index 994d4bd0b..b1cfeefcd 100644 --- a/rust-bins/src/bin/keygen-genesis.rs +++ b/rust-bins/src/bin/keygen-genesis.rs @@ -1,14 +1,18 @@ +use ark_bls12_381::{G1Projective, G2Projective}; use clap::AppSettings; use client_server_helpers::*; use concordium_base::{ - common::*, curve_arithmetic::Curve, elgamal::PublicKey, id::types::*, ps_sig, + common::*, curve_arithmetic::{Curve, arkworks_instances::ArkGroup}, elgamal::PublicKey, id::types::*, ps_sig, }; use curve25519_dalek::edwards::CompressedEdwardsY; -use pairing::bls12_381::{Bls12, G1, G2}; use sha2::{Digest, Sha512}; use std::{fs, path::PathBuf}; use structopt::StructOpt; +type Bls12 = ark_ec::bls12::Bls12; +type G1 = ArkGroup; +type G2 = ArkGroup; + #[derive(StructOpt)] struct KeygenIp { #[structopt(long = "seed", help = "File with seed.")] @@ -196,7 +200,7 @@ pub fn generate_ps_pk(n: u32, bytes: &[u8]) -> ps_sig::PublicKey { /// The difference is that this one does not concatenate the input /// to Sha512 with the single octet values 0 and 1, and neither does it /// concatenate with a public key. -pub fn hash_to_ed25519(msg: &[u8]) -> Option { +pub fn hash_to_ed25519(msg: &[u8]) -> Option { let mut p_candidate_bytes = [0u8; 32]; let mut h: Sha512 = Sha512::new(); h.update(b"concordium_genesis_ed25519"); @@ -212,7 +216,7 @@ pub fn hash_to_ed25519(msg: &[u8]) -> Option { // not be 0 after multiplying by cofactor. if !ed_point.is_small_order() { return Some( - ed25519_dalek::PublicKey::from_bytes( + ed25519_dalek::VerifyingKey::from_bytes( &ed_point.mul_by_cofactor().compress().to_bytes(), ) .unwrap(), diff --git a/rust-bins/src/bin/keygen.rs b/rust-bins/src/bin/keygen.rs index 617bd0cf0..c9d68b0e6 100644 --- a/rust-bins/src/bin/keygen.rs +++ b/rust-bins/src/bin/keygen.rs @@ -1,8 +1,9 @@ +use ark_bls12_381::{G1Projective, G2Projective}; use clap::AppSettings; use client_server_helpers::*; use concordium_base::{ common::*, - curve_arithmetic::Curve, + curve_arithmetic::{Curve, arkworks_instances::{ArkField, ArkGroup}}, elgamal::{PublicKey, SecretKey}, id::types::*, ps_sig, @@ -12,9 +13,9 @@ use crossterm::{ terminal::{Clear, ClearType}, }; use dialoguer::{Confirm, Input}; +use ed25519_dalek::SigningKey; use hmac::{Hmac, Mac}; use keygen_bls::{keygen_bls, keygen_bls_deprecated}; -use pairing::bls12_381::{Bls12, Fr, G1, G2}; use sha2::Sha512; use std::{ collections::HashMap, @@ -25,6 +26,11 @@ use std::{ }; use structopt::StructOpt; +type Bls12 = ark_ec::bls12::Bls12; +type G1 = ArkGroup; +type G2 = ArkGroup; +type Fr = ArkField; + const BIP39_ENGLISH: &str = include_str!("data/BIP39English.txt"); /// List of BIP39 words. There is a test that checks that this list has correct @@ -289,7 +295,8 @@ pub fn read_words_from_file( fn handle_generate_update_keys(kgup: KeygenGovernance) -> Result<(), String> { let mut csprng = rand::thread_rng(); let keypair = concordium_base::common::types::KeyPair::generate(&mut csprng); - let public_bytes = keypair.public.to_bytes(); + let signing_key: &SigningKey = keypair.as_ref(); + let public_bytes = signing_key.verifying_key().to_bytes(); let sig = keypair.sign(&public_bytes); let level_str = match kgup.level { Level::Root => "root", @@ -298,7 +305,7 @@ fn handle_generate_update_keys(kgup: KeygenGovernance) -> Result<(), String> { }; let public_data = serde_json::json!({ "key": { - "verifyKey": base16_encode_string(&keypair.public), + "verifyKey": base16_encode_string(&signing_key.verifying_key()), "scheme": "Ed25519", }, "signature": sig, @@ -529,8 +536,9 @@ fn handle_generate_ip_keys(kgip: KeygenIp) -> Result<(), String> { println!("Using deprecated BLS keygen."); } let ip_public_key = ps_sig::PublicKey::from(&ip_secret_key); - let ed_sk = succeed_or_die!(generate_ed_sk(&bytes_from_file), e => "Could not generate signature key for EdDSA because {}"); - let ed_pk = ed25519_dalek::PublicKey::from(&ed_sk); + let ed_sk = generate_ed_sk(&bytes_from_file); + let signing_key = ed25519_dalek::SigningKey::from_bytes(&ed_sk); + let ed_pk = signing_key.verifying_key(); let ip_cdi_verify_key = ed_pk; let ip_cdi_secret_key = ed_sk; let id = kgip.ip_identity; @@ -667,9 +675,8 @@ pub fn keygen_ed(seed: &[u8]) -> [u8; 32] { /// above. pub fn generate_ed_sk( seed: &[u8], -) -> Result { - let sk = ed25519_dalek::SecretKey::from_bytes(&keygen_ed(seed))?; - Ok(sk) +) -> ed25519_dalek::SecretKey { + keygen_ed(seed) } #[cfg(test)] diff --git a/rust-bins/src/bin/user_cli.rs b/rust-bins/src/bin/user_cli.rs index 4d38e4055..46c096b62 100644 --- a/rust-bins/src/bin/user_cli.rs +++ b/rust-bins/src/bin/user_cli.rs @@ -786,8 +786,8 @@ fn handle_create_credential_v1(cc: CreateCredentialV1) -> anyhow::Result<()> { }; let acc_data = { let mut keys = std::collections::BTreeMap::new(); - let public = ed25519::VerifyingKey::from(&secret); - keys.insert(KeyIndex(0), KeyPair { secret, public }); + let signing_key = ed25519::SigningKey::from_bytes(&secret); + keys.insert(KeyIndex(0), signing_key.into()); CredentialData { keys, diff --git a/rust-bins/src/lib.rs b/rust-bins/src/lib.rs index bb98a8039..da17abe94 100644 --- a/rust-bins/src/lib.rs +++ b/rust-bins/src/lib.rs @@ -7,7 +7,6 @@ use concordium_base::{ }; use dialoguer::Input; use hkdf::HkdfExtract; -use pairing::bls12_381::Bls12; use rand::Rng; use serde::{de::DeserializeOwned, Serialize as SerdeSerialize}; use serde_json::{to_string_pretty, to_writer_pretty}; @@ -21,6 +20,8 @@ use std::{ str::FromStr, }; +type Bls12 = ark_ec::bls12::Bls12; + pub type ExampleAttribute = AttributeKind; pub type ExampleAttributeList = AttributeList<::ScalarField, ExampleAttribute>; diff --git a/rust-src/concordium_base/benches/range_proof_dalek_bench.rs b/rust-src/concordium_base/benches/range_proof_dalek_bench.rs deleted file mode 100644 index 31768536f..000000000 --- a/rust-src/concordium_base/benches/range_proof_dalek_bench.rs +++ /dev/null @@ -1,57 +0,0 @@ -#![allow(non_snake_case)] - -use criterion::*; -use pprof::criterion::{Output, PProfProfiler}; -use rand::{rngs::OsRng, Rng}; -use std::time::Duration; - -use bulletproofs::{BulletproofGens, PedersenGens, RangeProof}; -use curve25519_dalek_ng::scalar::Scalar; -use merlin::Transcript; - -pub fn prove_verify_benchmarks(c: &mut Criterion) { - let n: usize = 32; - let m: usize = 16; - let mut group = c.benchmark_group("Range Proof over Dalek Curves"); - let pc_gens = PedersenGens::default(); - let bp_gens = BulletproofGens::new(n, m); - let mut rng = OsRng; - let (min, max) = (0u64, ((1u128 << n) - 1) as u64); - let values: Vec = (0..m).map(|_| rng.gen_range(min, max)).collect(); - let blindings: Vec = (0..m).map(|_| Scalar::random(&mut rng)).collect(); - let mut transcript = Transcript::new(b"AggregateRangeProofBenchmark"); - - group.bench_function("Prove", move |b| { - b.iter(|| { - RangeProof::prove_multiple(&bp_gens, &pc_gens, &mut transcript, &values, &blindings, n) - }) - }); - - let pc_gens = PedersenGens::default(); - let bp_gens = BulletproofGens::new(n, m); - let mut rng = rand::thread_rng(); - let (min, max) = (0u64, ((1u128 << n) - 1) as u64); - let values: Vec = (0..m).map(|_| rng.gen_range(min..max)).collect(); - let blindings: Vec = (0..m).map(|_| Scalar::random(&mut rng)).collect(); - let mut transcript = Transcript::new(b"AggregateRangeProofBenchmark"); - let (proof, value_commitments) = - RangeProof::prove_multiple(&bp_gens, &pc_gens, &mut transcript, &values, &blindings, n) - .unwrap(); - - group.bench_function("Verify Efficient", move |b| { - b.iter(|| { - let mut transcript = Transcript::new(b"AggregateRangeProofBenchmark"); - assert!(proof - .verify_multiple(&bp_gens, &pc_gens, &mut transcript, &value_commitments, n) - .is_ok()); - }) - }); -} - -criterion_group!( - name = benchmarks; - config = Criterion::default().measurement_time(Duration::from_millis(1000)).sample_size(10).with_profiler( - PProfProfiler::new(100, Output::Flamegraph(None)) - ); - targets = prove_verify_benchmarks); -criterion_main!(benchmarks); diff --git a/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs b/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs index 301a2460c..041f8c4a7 100644 --- a/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs +++ b/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs @@ -154,9 +154,8 @@ mod tests { pub fn test_ed25519_dlog() { let mut csprng = thread_rng(); for _ in 0..10000 { - let mut secret: SecretKey = [0u8; 32]; - csprng.fill_bytes(&mut secret); - let signing = SigningKey::from_bytes(&secret); + let signing = SigningKey::generate(&mut csprng); + let secret = signing.to_bytes(); let public = signing.verifying_key(); let challenge_prefix = generate_challenge_prefix(&mut csprng); let mut ro = RandomOracle::domain(&challenge_prefix); @@ -177,8 +176,8 @@ mod tests { pub fn test_ed25519_dlog_proof_serialization() { let mut csprng = thread_rng(); for _ in 0..10000 { - let mut secret: SecretKey = [0u8; 32]; - csprng.fill_bytes(&mut secret); + let signing = SigningKey::generate(&mut csprng); + let secret = signing.to_bytes(); let signing = SigningKey::from_bytes(&secret); let public = signing.verifying_key(); let challenge_prefix = generate_challenge_prefix(&mut csprng); diff --git a/rust-src/concordium_base/src/eddsa_ed25519/ffi.rs b/rust-src/concordium_base/src/eddsa_ed25519/ffi.rs index f4e956f00..d1483addd 100644 --- a/rust-src/concordium_base/src/eddsa_ed25519/ffi.rs +++ b/rust-src/concordium_base/src/eddsa_ed25519/ffi.rs @@ -12,27 +12,29 @@ use crate::random_oracle::RandomOracle; #[no_mangle] extern "C" fn eddsa_priv_key() -> *mut SecretKey { let mut csprng = thread_rng(); - let sk = SecretKey::generate(&mut csprng); - Box::into_raw(Box::new(sk)) + let mut secret_key = SecretKey::default(); + csprng.fill_bytes(&mut secret_key); + Box::into_raw(Box::new(secret_key)) } -// error encodeing +// error encoding //-1 bad input #[no_mangle] #[allow(clippy::not_unsafe_ptr_arg_deref)] -extern "C" fn eddsa_pub_key(sk_ptr: *mut SecretKey) -> *mut PublicKey { - let sk = from_ptr!(sk_ptr); - Box::into_raw(Box::new(PublicKey::from(sk))) +extern "C" fn eddsa_pub_key(sk_ptr: *mut SecretKey) -> *mut VerifyingKey { + let secret_key = from_ptr!(sk_ptr); + let signing_key = SigningKey::from_bytes(secret_key); + Box::into_raw(Box::new(signing_key.verifying_key())) } macro_free_ffi!(Box eddsa_sign_free, SecretKey); -macro_free_ffi!(Box eddsa_public_free, PublicKey); +macro_free_ffi!(Box eddsa_public_free, VerifyingKey); #[no_mangle] #[allow(clippy::not_unsafe_ptr_arg_deref)] extern "C" fn eddsa_sign_to_bytes(input_ptr: *mut SecretKey, output_len: *mut size_t) -> *const u8 { let input = from_ptr!(input_ptr); - let bytes = input.to_bytes().to_vec(); + let bytes = input.to_vec(); unsafe { *output_len = bytes.len() as size_t } let ret_ptr = bytes.as_ptr(); ::std::mem::forget(bytes); @@ -42,7 +44,7 @@ extern "C" fn eddsa_sign_to_bytes(input_ptr: *mut SecretKey, output_len: *mut si #[no_mangle] #[allow(clippy::not_unsafe_ptr_arg_deref)] extern "C" fn eddsa_public_to_bytes( - input_ptr: *mut PublicKey, + input_ptr: *mut VerifyingKey, output_len: *mut size_t, ) -> *const u8 { let input = from_ptr!(input_ptr); @@ -55,13 +57,21 @@ extern "C" fn eddsa_public_to_bytes( #[no_mangle] #[allow(clippy::not_unsafe_ptr_arg_deref)] -extern "C" fn eddsa_public_from_bytes(input_bytes: *mut u8, input_len: size_t) -> *mut PublicKey { +extern "C" fn eddsa_public_from_bytes( + input_bytes: *mut u8, + input_len: size_t, +) -> *mut VerifyingKey { let len = input_len; let bytes = slice_from_c_bytes!(input_bytes, len); - let e = PublicKey::from_bytes(bytes); - match e { - Ok(r) => Box::into_raw(Box::new(r)), - Err(_) => ::std::ptr::null_mut(), + let res: Result<[u8; 32], _> = bytes.try_into(); + if let Ok(byte_array) = res { + let e = VerifyingKey::from_bytes(&byte_array); + match e { + Ok(r) => Box::into_raw(Box::new(r)), + Err(_) => ::std::ptr::null_mut(), + } + } else { + ::std::ptr::null_mut() } } @@ -70,8 +80,8 @@ extern "C" fn eddsa_public_from_bytes(input_bytes: *mut u8, input_len: size_t) - extern "C" fn eddsa_sign_from_bytes(input_bytes: *mut u8, input_len: size_t) -> *mut SecretKey { let len = input_len; let bytes = slice_from_c_bytes!(input_bytes, len); - let e = SecretKey::from_bytes(bytes); - match e { + let res: Result<[u8; 32], _> = bytes.try_into(); + match res { Ok(r) => Box::into_raw(Box::new(r)), Err(_) => ::std::ptr::null_mut(), } @@ -83,14 +93,12 @@ extern "C" fn eddsa_sign( message: *const u8, len: usize, sk_ptr: *mut SecretKey, - pk_ptr: *mut PublicKey, signature_bytes: &mut [u8; SIGNATURE_LENGTH], ) { let sk = from_ptr!(sk_ptr); - let pk = from_ptr!(pk_ptr); let data: &[u8] = slice_from_c_bytes!(message, len); - let expanded_sk = ExpandedSecretKey::from(sk); - let signature = expanded_sk.sign(data, pk); + let expanded_sk = SigningKey::from(sk); + let signature = expanded_sk.sign(data); signature_bytes.copy_from_slice(&signature.to_bytes()); } // Error encoding @@ -101,7 +109,7 @@ extern "C" fn eddsa_sign( extern "C" fn eddsa_verify( message: *const u8, len: usize, - pk_ptr: *mut PublicKey, + pk_ptr: *mut VerifyingKey, signature_bytes: &[u8; SIGNATURE_LENGTH], ) -> i32 { let sig = match Signature::try_from(&signature_bytes[..]) { @@ -127,9 +135,14 @@ extern "C" fn eddsa_verify_dlog_ed25519( let challenge = slice_from_c_bytes!(challenge_prefix_ptr, challenge_len); let public_key = { let pk_bytes = slice_from_c_bytes!(public_key_bytes, PUBLIC_KEY_LENGTH); - match PublicKey::from_bytes(pk_bytes) { - Err(_) => return -1, - Ok(pk) => pk, + let res: Result<[u8; 32], _> = pk_bytes.try_into(); + if let Ok(pk_byte_array) = res { + match VerifyingKey::from_bytes(&pk_byte_array) { + Err(_) => return -1, + Ok(pk) => pk, + } + } else { + return -1; } }; let proof = { @@ -158,16 +171,23 @@ extern "C" fn eddsa_prove_dlog_ed25519( let challenge = slice_from_c_bytes!(challenge_prefix_ptr, challenge_len); let public_key = { let pk_bytes = slice_from_c_bytes!(public_key_bytes, PUBLIC_KEY_LENGTH); - match PublicKey::from_bytes(pk_bytes) { - Err(_) => return -1, - Ok(pk) => pk, + let res: Result<[u8; PUBLIC_KEY_LENGTH], _> = pk_bytes.try_into(); + if let Ok(pk_byte_array) = res { + match VerifyingKey::from_bytes(&pk_byte_array) { + Err(_) => return -1, + Ok(pk) => pk, + } + } else { + return -1; } }; let secret_key = { let sk_bytes = slice_from_c_bytes!(secret_key_bytes, SECRET_KEY_LENGTH); - match SecretKey::from_bytes(sk_bytes) { - Err(_) => return -2, - Ok(sk) => sk, + let res: Result<[u8; 32], _> = sk_bytes.try_into(); + if let Ok(sk_byte_array) = res { + sk_byte_array + } else { + return -2; } }; let proof_bytes = mut_slice_from_c_bytes!(proof_ptr, PROOF_LENGTH); diff --git a/rust-src/concordium_base/src/id/account_holder.rs b/rust-src/concordium_base/src/id/account_holder.rs index 2ba7f2a82..990a10c8c 100644 --- a/rust-src/concordium_base/src/id/account_holder.rs +++ b/rust-src/concordium_base/src/id/account_holder.rs @@ -1260,10 +1260,7 @@ mod tests { use crate::{ common::types::{KeyIndex, KeyPair}, - curve_arithmetic::{ - arkworks_instances::ArkGroup, - Curve, - }, + curve_arithmetic::{arkworks_instances::ArkGroup, Curve}, id::{constants::*, identity_provider::*, secret_sharing::Threshold, test::*}, pedersen_commitment::CommitmentKey as PedersenKey, }; diff --git a/rust-src/concordium_base/src/id/constants.rs b/rust-src/concordium_base/src/id/constants.rs index a6356f0f0..aec997f31 100644 --- a/rust-src/concordium_base/src/id/constants.rs +++ b/rust-src/concordium_base/src/id/constants.rs @@ -6,10 +6,7 @@ use crate::{ Buffer, Deserial, Get, ParseResult, Put, ReadBytesExt, SerdeDeserialize, SerdeSerialize, Serial, }, - curve_arithmetic::{ - arkworks_instances::ArkGroup, - Curve, Pairing, - }, + curve_arithmetic::{arkworks_instances::ArkGroup, Curve, Pairing}, }; use anyhow::bail; use ark_bls12_381::{g1, G1Projective}; diff --git a/rust-src/concordium_base/src/id/identity_provider.rs b/rust-src/concordium_base/src/id/identity_provider.rs index f07bbc957..cfb978642 100644 --- a/rust-src/concordium_base/src/id/identity_provider.rs +++ b/rust-src/concordium_base/src/id/identity_provider.rs @@ -547,21 +547,16 @@ pub fn create_initial_cdi< cred_account: pub_info_for_ip.vk_acc, }; - let sig = sign_initial_cred_values(&cred_values, expiry, ip_info, ip_cdi_secret_key); + let sig = sign_initial_cred_values(&cred_values, expiry, ip_cdi_secret_key); InitialCredentialDeploymentInfo { values: cred_values, sig, } } -fn sign_initial_cred_values< - P: Pairing, - C: Curve, - AttributeType: Attribute, ->( +fn sign_initial_cred_values>( initial_cred_values: &InitialCredentialDeploymentValues, expiry: TransactionTime, - ip_info: &IpInfo

, ip_cdi_secret_key: &ed25519_dalek::SecretKey, ) -> IpCdiSignature { let mut hasher = Sha256::new(); diff --git a/rust-src/concordium_base/src/id/test.rs b/rust-src/concordium_base/src/id/test.rs index 9c4ef5e44..e40b74655 100644 --- a/rust-src/concordium_base/src/id/test.rs +++ b/rust-src/concordium_base/src/id/test.rs @@ -71,9 +71,8 @@ pub fn test_create_ip_info( let ps_len = (5 + num_ars + max_attrs) as usize; let ip_secret_key = crate::ps_sig::SecretKey::::generate(ps_len, csprng); let ip_verify_key = crate::ps_sig::PublicKey::from(&ip_secret_key); - let mut secret = [0u8; 32]; - csprng.fill_bytes(&mut secret); - let signing = SigningKey::from_bytes(&secret); + let signing = SigningKey::generate(csprng); + let secret = signing.to_bytes(); let ip_cdi_verify_key = signing.verifying_key(); let ip_cdi_secret_key = secret; diff --git a/rust-src/ed25519_hd_key_derivation/src/lib.rs b/rust-src/ed25519_hd_key_derivation/src/lib.rs index cda9d18bc..7564d8a44 100644 --- a/rust-src/ed25519_hd_key_derivation/src/lib.rs +++ b/rust-src/ed25519_hd_key_derivation/src/lib.rs @@ -1,4 +1,3 @@ -use ed25519_dalek::SignatureError; use hmac::{Hmac, Mac}; use regex::Regex; use sha2::Sha512; From 5cd91fcc021fb0b56e9f1523d09f128223267694 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 4 Jan 2024 10:05:51 +0100 Subject: [PATCH 10/53] Use Scalar::from_bits() even though it is depricated; bump ed25519 version in wallet_library --- rust-src/Cargo.lock | 58 +++---------------- rust-src/concordium_base/Cargo.toml | 4 +- .../concordium_base/benches/bulletproofs.rs | 5 +- rust-src/concordium_base/src/ecvrf/mod.rs | 2 +- rust-src/concordium_base/src/ecvrf/public.rs | 2 +- rust-src/concordium_base/src/ecvrf/secret.rs | 2 +- .../src/eddsa_ed25519/dlog_ed25519.rs | 2 +- rust-src/wallet_library/Cargo.toml | 2 +- rust-src/wallet_library/src/credential.rs | 6 +- 9 files changed, 22 insertions(+), 61 deletions(-) diff --git a/rust-src/Cargo.lock b/rust-src/Cargo.lock index 2e8f57708..eadd7e3db 100644 --- a/rust-src/Cargo.lock +++ b/rust-src/Cargo.lock @@ -514,9 +514,9 @@ dependencies = [ "concordium-contracts-common", "concordium_base_derive", "criterion", - "curve25519-dalek 4.1.1", + "curve25519-dalek", "derive_more", - "ed25519-dalek 2.0.0", + "ed25519-dalek", "either", "ff 0.13.0", "group 0.2.0", @@ -669,19 +669,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - [[package]] name = "curve25519-dalek" version = "4.1.1" @@ -810,15 +797,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ed25519" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" -dependencies = [ - "signature 1.6.4", -] - [[package]] name = "ed25519" version = "2.2.2" @@ -826,21 +804,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" dependencies = [ "pkcs8", - "signature 2.1.0", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" -dependencies = [ - "curve25519-dalek 3.2.0", - "ed25519 1.5.3", - "rand 0.7.3", - "serde", - "sha2 0.9.9", - "zeroize", + "signature", ] [[package]] @@ -849,8 +813,8 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek 4.1.1", - "ed25519 2.2.2", + "curve25519-dalek", + "ed25519", "rand_core 0.6.4", "serde", "sha2 0.10.7", @@ -861,7 +825,7 @@ dependencies = [ name = "ed25519_hd_key_derivation" version = "1.0.0" dependencies = [ - "ed25519-dalek 2.0.0", + "ed25519-dalek", "hex", "hmac", "regex", @@ -1163,7 +1127,7 @@ name = "key_derivation" version = "2.1.0" dependencies = [ "concordium_base", - "ed25519-dalek 2.0.0", + "ed25519-dalek", "ed25519_hd_key_derivation", "hex", "hmac", @@ -1857,12 +1821,6 @@ dependencies = [ "sha2 0.10.7", ] -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" - [[package]] name = "signature" version = "2.1.0" @@ -2053,7 +2011,7 @@ version = "0.1.0" dependencies = [ "anyhow", "concordium_base", - "ed25519-dalek 1.0.1", + "ed25519-dalek", "hex", "key_derivation", "serde", diff --git a/rust-src/concordium_base/Cargo.toml b/rust-src/concordium_base/Cargo.toml index 812ed1fcb..6da5c4bdb 100644 --- a/rust-src/concordium_base/Cargo.toml +++ b/rust-src/concordium_base/Cargo.toml @@ -27,7 +27,7 @@ serde_json = "1.0" libc = "0.2" chrono = {version = "0.4.24", features = ["serde"]} # the patch version is necessary since chrono adds new functionality in patch versions serde_with = "3" -ed25519-dalek = {version = "2.0", features = ["rand_core"]} +ed25519-dalek = {version = "2.0", features = ["rand_core", "legacy_compatibility"]} byteorder = "1.3" hex = "0.4" itertools = "0.10" @@ -37,7 +37,7 @@ thiserror = "1.0" rand = "0.8" num = "0.4" group = "0.2" -curve25519-dalek = { version = "4", features = ["rand_core", "group"]} +curve25519-dalek = { version = "4.1.1", features = ["rand_core", "group"]} zeroize = "1.1" # See https://github.com/serde-rs/json/issues/505 for the need to be careful. rust_decimal = { version = "1.25", features = ["serde-float", "serde-arbitrary-precision"]} diff --git a/rust-src/concordium_base/benches/bulletproofs.rs b/rust-src/concordium_base/benches/bulletproofs.rs index 736399f02..759a37773 100644 --- a/rust-src/concordium_base/benches/bulletproofs.rs +++ b/rust-src/concordium_base/benches/bulletproofs.rs @@ -7,7 +7,7 @@ use ark_bls12_381::{Fr, G1Projective}; use concordium_base::{ bulletproofs::{inner_product_proof::*, range_proof::*, utils::Generators}, curve_arithmetic::{ - arkworks_instances::{ArkField, ArkGroup}, + arkworks_instances::ArkGroup, *, }, id::id_proof_types::ProofVersion, @@ -16,10 +16,11 @@ use concordium_base::{ }; use criterion::Criterion; use curve25519_dalek::ristretto::RistrettoPoint; -use pairing::bls12_381::G1; use rand::*; use std::time::Duration; +type G1 = ArkGroup; + pub fn prove_verify_benchmarks(c: &mut Criterion) { let bench_group_name = "Range Proof for ".to_owned() + std::any::type_name::(); let mut group = c.benchmark_group(bench_group_name); diff --git a/rust-src/concordium_base/src/ecvrf/mod.rs b/rust-src/concordium_base/src/ecvrf/mod.rs index c365b3518..2da0fae6f 100644 --- a/rust-src/concordium_base/src/ecvrf/mod.rs +++ b/rust-src/concordium_base/src/ecvrf/mod.rs @@ -262,7 +262,7 @@ mod tests { // Test serialization of generated secret scalar let x = expanded_sk.key; - assert_eq!(x, Scalar::from_bytes_mod_order(x_bytes)); + assert_eq!(x, Scalar::from_bits(x_bytes)); // Test serialization of proof let proof = expanded_sk.prove(&pk, &alpha_bytes); diff --git a/rust-src/concordium_base/src/ecvrf/public.rs b/rust-src/concordium_base/src/ecvrf/public.rs index 188d8968f..8bf072969 100644 --- a/rust-src/concordium_base/src/ecvrf/public.rs +++ b/rust-src/concordium_base/src/ecvrf/public.rs @@ -94,7 +94,7 @@ impl PublicKey { fn mangle_scalar_bits_and_multiply_by_basepoint_to_produce_public_key( bits: &mut [u8; 32], ) -> PublicKey { - let scalar = Scalar::from_bytes_mod_order(clamp_integer(*bits)); + let scalar = Scalar::from_bits(clamp_integer(*bits)); let point = &scalar * constants::ED25519_BASEPOINT_TABLE; let compressed = point.compress(); diff --git a/rust-src/concordium_base/src/ecvrf/secret.rs b/rust-src/concordium_base/src/ecvrf/secret.rs index ba023d794..15b7ccef4 100644 --- a/rust-src/concordium_base/src/ecvrf/secret.rs +++ b/rust-src/concordium_base/src/ecvrf/secret.rs @@ -126,7 +126,7 @@ impl From<&SecretKey> for ExpandedSecretKey { lower.copy_from_slice(&hash[00..32]); upper.copy_from_slice(&hash[32..64]); - let scalar = Scalar::from_bytes_mod_order(clamp_integer(lower)); + let scalar = Scalar::from_bits(clamp_integer(lower)); ExpandedSecretKey { key: scalar, diff --git a/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs b/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs index 041f8c4a7..c9795054c 100644 --- a/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs +++ b/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs @@ -67,7 +67,7 @@ fn scalar_from_secret_key(secret_key: &impl AsRef<[u8]>) -> Scalar { h.update(secret_key); hash.copy_from_slice(h.finalize().as_slice()); scalar_bytes.copy_from_slice(&hash[..32]); - Scalar::from_bytes_mod_order(clamp_integer(scalar_bytes)) + Scalar::from_bits(clamp_integer(scalar_bytes)) } fn point_from_public_key(public_key: &VerifyingKey) -> Option { diff --git a/rust-src/wallet_library/Cargo.toml b/rust-src/wallet_library/Cargo.toml index e80b909f7..97a2cf43d 100644 --- a/rust-src/wallet_library/Cargo.toml +++ b/rust-src/wallet_library/Cargo.toml @@ -25,4 +25,4 @@ name = "wallet_library" crate-type = ["rlib"] [dev-dependencies] -ed25519-dalek = "1.0.0" +ed25519-dalek = "2.0.0" diff --git a/rust-src/wallet_library/src/credential.rs b/rust-src/wallet_library/src/credential.rs index 9a2090686..115f91067 100644 --- a/rust-src/wallet_library/src/credential.rs +++ b/rust-src/wallet_library/src/credential.rs @@ -264,10 +264,12 @@ mod tests { attribute_randomness.insert(tag, randomness); } - let key = ed25519::PublicKey::from_bytes( + let key = ed25519::VerifyingKey::from_bytes( hex::decode("29723ec9a0b4ca16d5d548b676a1a0adbecdedc5446894151acb7699293d69b1") .unwrap() - .as_slice(), + .as_slice() + .try_into() + .unwrap(), ) .unwrap(); let mut key_map: BTreeMap = BTreeMap::new(); From 60cc852205af95be7febbda39a7d10b65d6b13e4 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 4 Jan 2024 13:39:39 +0100 Subject: [PATCH 11/53] Update changelog --- rust-src/concordium_base/CHANGELOG.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/rust-src/concordium_base/CHANGELOG.md b/rust-src/concordium_base/CHANGELOG.md index 391b5a3ca..9cc24ece5 100644 --- a/rust-src/concordium_base/CHANGELOG.md +++ b/rust-src/concordium_base/CHANGELOG.md @@ -1,8 +1,15 @@ ## Unreleased changes -- Improve performance of `multiexp*` family of functions. -- Add traits `Field` and `PrimeField` with implementations for the underlying field of the `BLS12-381`` curve. - Add `MultiExp` trait that allows to have different `multiexp` algorithm implementations for different curves. +- Improve performance of the generic `multiexp` algorithm. +- Add an instance of `MultiExp` that is specific to `curve25519`. +- Add traits `Field` and `PrimeField` with implementations for the underlying field of the `BLS12-381` curve. +- Add integration with the `arkworks` library interfaces for fields and elliptic curves (wrapper types and blanket trait implementations). +- Add the `BLS12-381`implementation from the `arkworks` ecosystem. +- Remove the `pairing` crate from dependencies along with the corresponding `BLS12-381` code (replaced with the `arkworks` implementation). +- Upgrade `ed25519-dalek` to `v2.0`. This leads to changes in FFI: + * the `pk_ptr` parameter is removed from `eddsa_sign` function; it is sufficient to supply a pointer to the secret key data. +- Bump the `rand` version to `v0.8` - Add implementations of `Field`, `PrimeField` and `Curve` for the Ristretto representation of `curve25519`. - Support `P7` protocol version. - The `Debug` implementation for `ContractEvent` displays the value in `hex`. From a24a9230bda8182a64b523f07b9b937be43a2f6d Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 4 Jan 2024 14:59:02 +0100 Subject: [PATCH 12/53] Cleanup and documentation --- .../concordium_base/benches/bulletproofs.rs | 5 +- .../curve_arithmetic/arkworks_instances.rs | 58 ++++++++++--------- .../curve_arithmetic/bls12_381_arkworks.rs | 12 +++- .../src/curve_arithmetic/ed25519_arkworks.rs | 7 --- .../src/curve_arithmetic/ed25519_instance.rs | 6 +- .../src/curve_arithmetic/field_adapters.rs | 10 ++++ .../src/curve_arithmetic/mod.rs | 1 - 7 files changed, 57 insertions(+), 42 deletions(-) delete mode 100644 rust-src/concordium_base/src/curve_arithmetic/ed25519_arkworks.rs diff --git a/rust-src/concordium_base/benches/bulletproofs.rs b/rust-src/concordium_base/benches/bulletproofs.rs index 759a37773..e9249bd3b 100644 --- a/rust-src/concordium_base/benches/bulletproofs.rs +++ b/rust-src/concordium_base/benches/bulletproofs.rs @@ -6,10 +6,7 @@ extern crate criterion; use ark_bls12_381::{Fr, G1Projective}; use concordium_base::{ bulletproofs::{inner_product_proof::*, range_proof::*, utils::Generators}, - curve_arithmetic::{ - arkworks_instances::ArkGroup, - *, - }, + curve_arithmetic::{arkworks_instances::ArkGroup, *}, id::id_proof_types::ProofVersion, pedersen_commitment::*, random_oracle::RandomOracle, diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index b15fee625..00ee46785 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -1,3 +1,5 @@ +//! Wrapper types and blanket implementations serving as adapters from +//! `arkworks` field/curve traits. use core::fmt; use std::str::FromStr; @@ -8,32 +10,18 @@ use anyhow::anyhow; use ark_ec::hashing::HashToCurve; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -#[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, fmt::Debug)] +/// A wrapper type for `arkworks` field types. +#[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, fmt::Debug, derive_more::From)] pub struct ArkField(pub(crate) F); -impl From for ArkField { - fn from(value: F) -> Self { ArkField(value) } -} - -// impl Serial for ArkField { -// fn serial(&self, out: &mut B) { -// self.0 -// .serialize_compressed(out) -// .expect("Serialzation expected to succeed") -// } -// } - -// impl Deserial for ArkField { -// fn deserial(source: &mut R) -> -// crate::common::ParseResult { let res = -// F::deserialize_compressed(source)?; Ok(res.into()) -// } -// } - +/// Serialization is implemented by delegating the functionality to the wrapped +/// type. impl Serial for ArkField { fn serial(&self, out: &mut B) { self.0.serial(out) } } +/// Deserialization is implemented by delegating the functionality to the +/// wrapped type. impl Deserial for ArkField { fn deserial(source: &mut R) -> crate::common::ParseResult { let res = F::deserial(source)?; @@ -41,6 +29,9 @@ impl Deserial for ArkField { } } +/// A blanket implementation of the `Field` trait using the functionality of +/// `ark_ff::Field`. This gives an implementation of our `Field` trait for +/// `ArkField` for any `F` that implements `ark_ff::Field`. impl Field for ArkField { fn random(rng: &mut R) -> Self { F::rand(rng).into() @@ -71,7 +62,10 @@ impl ArkField { pub fn into_ark(&self) -> &F { &self.0 } } -impl PrimeField for ArkField { +/// A blanket implementation of the `PrimeField` trait using the functionality +/// of `ark_ff::PrimeField`. This gives an implementation of our `PrimeField` +/// trait for `ArkField` for any `F` that implements `ark_ff::PrimeField`. +impl PrimeField for ArkField { const CAPACITY: u32 = Self::NUM_BITS - 1; const NUM_BITS: u32 = F::MODULUS_BIT_SIZE; @@ -95,13 +89,16 @@ impl PrimeField for ArkField { } } -#[derive(PartialEq, Eq, Copy, Clone, fmt::Debug)] +/// A wrapper type for `arkworks` group types. +#[derive(PartialEq, Eq, Copy, Clone, fmt::Debug, derive_more::From)] pub struct ArkGroup(pub(crate) G); impl ArkGroup { pub fn into_ark(&self) -> &G { &self.0 } } +/// Serialization is implemented by delegating the functionality to the +/// compressed affine representation of `ark_ec:CurveGroup`. impl Serial for ArkGroup { fn serial(&self, out: &mut B) { self.0 @@ -111,6 +108,8 @@ impl Serial for ArkGroup { } } +/// Deserialization is implemented by delegating the functionality to the +/// compressed affine representation of `ark_ec:CurveGroup`. impl Deserial for ArkGroup { fn deserial(source: &mut R) -> crate::common::ParseResult { let res = G::Affine::deserialize_compressed(source)?; @@ -118,10 +117,10 @@ impl Deserial for ArkGroup { } } -impl From for ArkGroup { - fn from(value: G) -> Self { ArkGroup(value) } -} - +/// Curve configuration. +/// +/// These parameters cannot be taken from the `arkworks` traits. Each `arkworks` +/// curve should come with an implementation of this configuration trait. pub(crate) trait ArkCurveConfig { const SCALAR_LENGTH: usize; const GROUP_ELEMENT_LENGTH: usize; @@ -129,6 +128,11 @@ pub(crate) trait ArkCurveConfig { type Hasher: ark_ec::hashing::HashToCurve; } +/// A blanket implementation of the `Curve` trait using the functionality of +/// `ark_ec::CurveGroup` and curve configuration `ArkCurveConfig`. This gives an +/// implementation of our `Curve` trait for `ArkGroup` for any `F` that +/// implements `ark_ec::CurveGroup`, provided an instance of `ArkCurveConfig` +/// for that curve. impl> Curve for ArkGroup where ::ScalarField: Serialize, @@ -157,7 +161,7 @@ where fn bytes_to_curve_unchecked(b: &mut R) -> anyhow::Result { // TODO: this is not the most efficient implementation, since there might be - // some additional checks durind deserialization. However, it seems + // some additional checks during deserialization. However, it seems // there are no unchecked methods available through traits. let res = G::Affine::deserialize_compressed(b).map_err(|e| anyhow!(e))?; Ok(ArkGroup(res.into())) diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 688bbe266..d5448d59c 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -1,3 +1,6 @@ +//! Trait implementations for the BLS12-381 curve from `arkworks`. +//! Include configuration for `G1` and `G2`, `Pairing`, and serialization for +//! the target group elements. use core::fmt; use ark_bls12_381::*; @@ -170,7 +173,7 @@ mod tests { 0, 0, 0, 0, 0, 0, 0, ]; - // Check that scalar_from_bytes_helper works on small values. + /// Check that scalar_from_bytes_helper works on small values. #[test] fn scalar_from_bytes_small() { let mut rng = rand::thread_rng(); @@ -214,6 +217,7 @@ mod tests { } } + /// Test that the scalar serialization produces big-endian bytes. #[test] fn test_scalar_serialize_big_endian() { let bigint: BigUint = BigUint::from_bytes_le(&SCALAR_BYTES_LE); @@ -229,6 +233,8 @@ mod tests { assert_eq!(scalar_bytes_be, out); } + /// A macro for testing that serializing a scalar and deserializing it back + /// gives the same scalar. macro_rules! macro_test_scalar_byte_conversion { ($function_name:ident, $p:path) => { #[test] @@ -244,6 +250,8 @@ mod tests { }; } + /// A macro for testing that serializing a point and deserializing it back + /// gives the same point. macro_rules! macro_test_group_byte_conversion { ($function_name:ident, $p:path) => { #[test] @@ -259,6 +267,8 @@ mod tests { }; } + /// A macro for testing that serializing a point and converting it back + /// using `bytes_to_curve_unchecked` gives the same point. macro_rules! macro_test_group_byte_conversion_unchecked { ($function_name:ident, $p:path) => { #[test] diff --git a/rust-src/concordium_base/src/curve_arithmetic/ed25519_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/ed25519_arkworks.rs deleted file mode 100644 index ff3475cca..000000000 --- a/rust-src/concordium_base/src/curve_arithmetic/ed25519_arkworks.rs +++ /dev/null @@ -1,7 +0,0 @@ -use super::arkworks_instances::CurveElementLength; -use ark_curve25519::*; - -impl CurveElementLength for EdwardsProjective { - const GROUP_ELEMENT_LENGTH: usize = 32; - const SCALAR_LENGTH: usize = 32; -} diff --git a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs index 1de854954..3651a8abe 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs @@ -31,7 +31,6 @@ impl Deserial for Scalar { } } - impl PrimeField for FFField { const CAPACITY: u32 = ::CAPACITY; const NUM_BITS: u32 = ::NUM_BITS; @@ -205,7 +204,10 @@ impl MultiExp for RistrettoMultiExpNoPrecompute { #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::{common::*, curve_arithmetic::{field_adapters::FFField, Field}}; + use crate::{ + common::*, + curve_arithmetic::{field_adapters::FFField, Field}, + }; use curve25519_dalek::{ristretto::RistrettoPoint, Scalar}; use rand::{Rng, RngCore}; use std::io::Cursor; diff --git a/rust-src/concordium_base/src/curve_arithmetic/field_adapters.rs b/rust-src/concordium_base/src/curve_arithmetic/field_adapters.rs index e03386a4d..bafc43a8b 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/field_adapters.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/field_adapters.rs @@ -1,3 +1,5 @@ +//! Wrapper types and blanket implementations serving as adapters from +//! the `ff` crate `Field`. use ff; use rand::RngCore; @@ -5,13 +7,18 @@ use crate::common::{Deserial, Serial}; use super::Field; +/// A wrapper type for `ff` field types. #[derive(derive_more::From, Clone, Copy, Debug, PartialEq, Eq)] pub struct FFField(pub(crate) F); +/// Serialization is implemented by delegating the functionality to the wrapped +/// type. impl Serial for FFField { fn serial(&self, out: &mut B) { self.0.serial(out) } } +/// Deserialization is implemented by delegating the functionality to the +/// wrapped type. impl Deserial for FFField { fn deserial(source: &mut R) -> crate::common::ParseResult { let res = F::deserial(source)?; @@ -19,6 +26,9 @@ impl Deserial for FFField { } } +/// A blanket implementation of the `Field` trait using the functionality of +/// `ff::Field`. This gives an implementation of our `Field` trait for +/// `FFField` for any `F` that implements `ff::Field`. impl Field for FFField { fn random(rng: &mut R) -> Self { F::random(rng).into() } diff --git a/rust-src/concordium_base/src/curve_arithmetic/mod.rs b/rust-src/concordium_base/src/curve_arithmetic/mod.rs index 8f49a1f22..6d3ba9878 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/mod.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/mod.rs @@ -1,7 +1,6 @@ //! Basic definitions of the curve and pairing abstractions, and implementations //! of these abstractions for the curves used on Concordium. pub mod arkworks_instances; -// mod ed25519_arkworks; mod bls12_381_arkworks; mod ed25519_instance; mod field_adapters; From 2a78f2063ffeb2b01a59bcaa5f226d93491cd948 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 4 Jan 2024 15:54:01 +0100 Subject: [PATCH 13/53] Formatting --- identity-provider-service/src/bin/main.rs | 11 ++++------- rust-src/ed25519_hd_key_derivation/src/lib.rs | 2 +- rust-src/keygen_bls/src/lib.rs | 12 +++++++++--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/identity-provider-service/src/bin/main.rs b/identity-provider-service/src/bin/main.rs index 46bed442d..d8ba21b11 100644 --- a/identity-provider-service/src/bin/main.rs +++ b/identity-provider-service/src/bin/main.rs @@ -15,7 +15,7 @@ use concordium_base::{ types::*, }, }; -use ed25519_dalek::{SigningKey, Signer}; +use ed25519_dalek::{Signer, SigningKey}; use log::{error, info, warn}; use reqwest::Client; use serde_json::{from_str, json, to_value}; @@ -962,10 +962,8 @@ async fn save_validated_request( // Sign the id_cred_pub so that the identity verifier can verify that the given // id_cred_pub matches a valid identity creation request. - let expanded_secret_key = - SigningKey::from(&server_config.ip_data.ip_cdi_secret_key); - let signature_on_id_cred_pub = - expanded_secret_key.sign(id_cred_pub_hash.as_slice()); + let expanded_secret_key = SigningKey::from(&server_config.ip_data.ip_cdi_secret_key); + let signature_on_id_cred_pub = expanded_secret_key.sign(id_cred_pub_hash.as_slice()); let serialized_signature = base16_encode_string(&signature_on_id_cred_pub); ok_or_500!( @@ -1001,8 +999,7 @@ async fn save_validated_request_v1( // id_cred_pub matches a valid identity creation request. let expanded_secret_key: SigningKey = SigningKey::from(&server_config.ip_data.ip_cdi_secret_key); - let signature_on_id_cred_pub = - expanded_secret_key.sign(id_cred_pub_hash.as_slice()); + let signature_on_id_cred_pub = expanded_secret_key.sign(id_cred_pub_hash.as_slice()); let serialized_signature = base16_encode_string(&signature_on_id_cred_pub); ok_or_500!( diff --git a/rust-src/ed25519_hd_key_derivation/src/lib.rs b/rust-src/ed25519_hd_key_derivation/src/lib.rs index 7564d8a44..0612a2811 100644 --- a/rust-src/ed25519_hd_key_derivation/src/lib.rs +++ b/rust-src/ed25519_hd_key_derivation/src/lib.rs @@ -179,7 +179,7 @@ pub fn derive_from_parsed_path(parsed_path: &[u32], seed: &[u8]) -> Result Result, hkdf::Inv /// an integer modulo r. It therefore does not follow the standard (cf. ), /// but is still secure. /// This function is needed for backwards compatibility. -pub fn keygen_bls_deprecated(ikm: &[u8], key_info: &[u8]) -> Result, hkdf::InvalidLength> { +pub fn keygen_bls_deprecated( + ikm: &[u8], + key_info: &[u8], +) -> Result, hkdf::InvalidLength> { let mut ikm = ikm.to_vec(); ikm.push(0); let l = 48; // = 48 for G1; r is From d7f18632045ba5cd73bd16c6328e6f60ca3ab4b6 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Fri, 5 Jan 2024 08:47:32 +0100 Subject: [PATCH 14/53] More formatting --- rust-bins/src/bin/client.rs | 3 ++- rust-bins/src/bin/generate_testdata.rs | 2 +- rust-bins/src/bin/keygen-genesis.rs | 6 +++++- rust-bins/src/bin/keygen.rs | 11 +++++------ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/rust-bins/src/bin/client.rs b/rust-bins/src/bin/client.rs index 46d8cf038..8f7060276 100644 --- a/rust-bins/src/bin/client.rs +++ b/rust-bins/src/bin/client.rs @@ -6,6 +6,7 @@ use concordium_base::{ types::{Amount, CredentialIndex, KeyIndex, KeyPair, TransactionTime}, *, }, + curve_arithmetic::arkworks_instances::ArkGroup, dodis_yampolskiy_prf as prf, elgamal::{self, PublicKey, SecretKey}, id::{ @@ -18,7 +19,7 @@ use concordium_base::{ types::*, }, pedersen_commitment::Value as PedersenValue, - ps_sig, curve_arithmetic::arkworks_instances::ArkGroup, + ps_sig, }; use dialoguer::{Input, MultiSelect, Select}; use ed25519_dalek as ed25519; diff --git a/rust-bins/src/bin/generate_testdata.rs b/rust-bins/src/bin/generate_testdata.rs index 7f60bbd97..daf49a1a9 100644 --- a/rust-bins/src/bin/generate_testdata.rs +++ b/rust-bins/src/bin/generate_testdata.rs @@ -6,7 +6,7 @@ use concordium_base::{ types::{KeyIndex, KeyPair, TransactionTime}, *, }, - curve_arithmetic::{Curve, Pairing, arkworks_instances::ArkGroup}, + curve_arithmetic::{arkworks_instances::ArkGroup, Curve, Pairing}, dodis_yampolskiy_prf as prf, id::{ account_holder::*, diff --git a/rust-bins/src/bin/keygen-genesis.rs b/rust-bins/src/bin/keygen-genesis.rs index b1cfeefcd..d3c79b67a 100644 --- a/rust-bins/src/bin/keygen-genesis.rs +++ b/rust-bins/src/bin/keygen-genesis.rs @@ -2,7 +2,11 @@ use ark_bls12_381::{G1Projective, G2Projective}; use clap::AppSettings; use client_server_helpers::*; use concordium_base::{ - common::*, curve_arithmetic::{Curve, arkworks_instances::ArkGroup}, elgamal::PublicKey, id::types::*, ps_sig, + common::*, + curve_arithmetic::{arkworks_instances::ArkGroup, Curve}, + elgamal::PublicKey, + id::types::*, + ps_sig, }; use curve25519_dalek::edwards::CompressedEdwardsY; use sha2::{Digest, Sha512}; diff --git a/rust-bins/src/bin/keygen.rs b/rust-bins/src/bin/keygen.rs index c9d68b0e6..5ac920791 100644 --- a/rust-bins/src/bin/keygen.rs +++ b/rust-bins/src/bin/keygen.rs @@ -3,7 +3,10 @@ use clap::AppSettings; use client_server_helpers::*; use concordium_base::{ common::*, - curve_arithmetic::{Curve, arkworks_instances::{ArkField, ArkGroup}}, + curve_arithmetic::{ + arkworks_instances::{ArkField, ArkGroup}, + Curve, + }, elgamal::{PublicKey, SecretKey}, id::types::*, ps_sig, @@ -673,11 +676,7 @@ pub fn keygen_ed(seed: &[u8]) -> [u8; 32] { /// It generates a ed25519_dalek secret key given a seed, using the `keygen_ed` /// above. -pub fn generate_ed_sk( - seed: &[u8], -) -> ed25519_dalek::SecretKey { - keygen_ed(seed) -} +pub fn generate_ed_sk(seed: &[u8]) -> ed25519_dalek::SecretKey { keygen_ed(seed) } #[cfg(test)] mod tests { From c0d933425f4e5e47a2264078bf930be8f8093902 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Fri, 5 Jan 2024 08:54:29 +0100 Subject: [PATCH 15/53] More formatting --- idiss/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idiss/src/lib.rs b/idiss/src/lib.rs index 5528a6ff0..7cf9385c3 100644 --- a/idiss/src/lib.rs +++ b/idiss/src/lib.rs @@ -2,7 +2,7 @@ use anyhow::Context; use ark_bls12_381::G1Projective; use concordium_base::{ common::{base16_decode_string, types::TransactionTime, Versioned, VERSION_0}, - curve_arithmetic::{*, arkworks_instances::ArkGroup}, + curve_arithmetic::{arkworks_instances::ArkGroup, *}, id, id::{ constants::{ArCurve, AttributeKind}, From 03beffbd74d84b1554bf8869e3fe70ad8375373d Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Fri, 5 Jan 2024 15:31:41 +0100 Subject: [PATCH 16/53] Fixes after clippy --- README.md | 2 +- .../curve_arithmetic/arkworks_instances.rs | 2 +- .../curve_arithmetic/bls12_381_arkworks.rs | 19 ++++++------------- .../src/curve_arithmetic/ed25519_instance.rs | 5 ++--- rust-src/concordium_base/src/ecvrf/public.rs | 8 ++++++++ rust-src/concordium_base/src/ecvrf/secret.rs | 8 ++++++++ .../src/eddsa_ed25519/dlog_ed25519.rs | 9 +++++++++ .../concordium_base/src/id/account_holder.rs | 4 ++-- rust-src/concordium_base/src/id/types.rs | 4 +--- rust-src/concordium_base/src/web3id/mod.rs | 4 ++-- 10 files changed, 40 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index ef579cfe9..6d0d0c4e5 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ Code should be formatted using [`fourmolu`](https://github.com/fourmolu/fourmolu version `0.13.1.0` and using the config `fourmolu.yaml` found in the project root. The CI is setup to ensure the code follows this style. -To check the formatting locally run the following commnad from the project root: +To check the formatting locally run the following command from the project root: **On unix-like systems**: diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 00ee46785..a06ac632c 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -196,7 +196,7 @@ where fn hash_to_group(m: &[u8]) -> Self { let hasher = G::Hasher::new(G::DOMAIN_STRING.as_ref()) .expect("Expected valid domain separation string"); - let res = G::Hasher::hash(&hasher, &m).expect("Expected successful hashing to curve"); + let res = G::Hasher::hash(&hasher, m).expect("Expected successful hashing to curve"); ArkGroup(res.into()) } } diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index d5448d59c..242ca82df 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -5,7 +5,6 @@ use core::fmt; use ark_bls12_381::*; use ark_ec::{ - bls12::{G1Prepared, G2Prepared}, hashing::{curve_maps::wb::WBMap, map_to_curve_hasher::MapToCurveBasedHasher}, pairing::MillerLoopOutput, short_weierstrass::Projective, @@ -49,7 +48,7 @@ impl ArkCurveConfig for Projective { impl Deserial for Fr { fn deserial(source: &mut R) -> ParseResult { let mut buf = [0u8; 32]; - source.read(&mut buf)?; + source.read_exact(&mut buf)?; // Construct the scalar from big endian bytes. let big_int: BigInt<4> = BigUint::from_bytes_be(&buf) .try_into() @@ -111,25 +110,19 @@ impl Pairing for Bls12 { type TargetField = ArkField<::TargetField>; #[inline(always)] - fn g1_prepare(g: &Self::G1) -> Self::G1Prepared { - let res: G1Prepared<_> = g.into_ark().into_affine().into(); - res.into() - } + fn g1_prepare(g: &Self::G1) -> Self::G1Prepared { g.into_ark().into_affine().into() } #[inline(always)] - fn g2_prepare(g: &Self::G2) -> Self::G2Prepared { - let res: G2Prepared<_> = g.into_ark().into_affine().into(); - res.into() - } + fn g2_prepare(g: &Self::G2) -> Self::G2Prepared { g.into_ark().into_affine().into() } #[inline(always)] fn miller_loop<'a, I>(i: I) -> Self::TargetField where I: IntoIterator, { - let (xs, ys): (Vec<_>, Vec<_>) = i.into_iter().map(|x| *x).unzip(); + let (xs, ys): (Vec<_>, Vec<_>) = i.into_iter().copied().unzip(); let res = ::multi_miller_loop( - xs.into_iter().map(|x| x.clone()), - ys.into_iter().map(|x| x.clone()), + xs.into_iter().cloned(), + ys.into_iter().cloned(), ) .0; res.into() diff --git a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs index 3651a8abe..f15288e3e 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs @@ -24,10 +24,9 @@ impl Deserial for Scalar { let mut buf: [u8; 32] = [0; 32]; source.read_exact(&mut buf)?; let res: Option<_> = Scalar::from_canonical_bytes(buf).into(); - let scalar: Scalar = res.ok_or(anyhow::anyhow!( + res.ok_or(anyhow::anyhow!( "Deserialization failed! Not a field value!" - ))?; - Ok(scalar.into()) + )) } } diff --git a/rust-src/concordium_base/src/ecvrf/public.rs b/rust-src/concordium_base/src/ecvrf/public.rs index 8bf072969..bd03b93d7 100644 --- a/rust-src/concordium_base/src/ecvrf/public.rs +++ b/rust-src/concordium_base/src/ecvrf/public.rs @@ -94,6 +94,14 @@ impl PublicKey { fn mangle_scalar_bits_and_multiply_by_basepoint_to_produce_public_key( bits: &mut [u8; 32], ) -> PublicKey { + // It seems like `from_bits` is the only way to construct an unreduced scalar + // that can potentially be grater than the field's order. + + // TODO: we use a + // deprecated `from_bits` here, this also requires enabling the + // `legacy_compatibility` feature for the `ed25519-dalek` dependency. Maybe ther + // is a different way of implementing this. + #[allow(deprecated)] let scalar = Scalar::from_bits(clamp_integer(*bits)); let point = &scalar * constants::ED25519_BASEPOINT_TABLE; diff --git a/rust-src/concordium_base/src/ecvrf/secret.rs b/rust-src/concordium_base/src/ecvrf/secret.rs index 15b7ccef4..4c1716ca9 100644 --- a/rust-src/concordium_base/src/ecvrf/secret.rs +++ b/rust-src/concordium_base/src/ecvrf/secret.rs @@ -126,6 +126,14 @@ impl From<&SecretKey> for ExpandedSecretKey { lower.copy_from_slice(&hash[00..32]); upper.copy_from_slice(&hash[32..64]); + // It seems like `from_bits` is the only way to construct an unreduced scalar + // that can potentially be grater than the field's order. + + // TODO: we use a + // deprecated `from_bits` here, this also requires enabling the + // `legacy_compatibility` feature for the `ed25519-dalek` dependency. Maybe ther + // is a different way of implementing this. + #[allow(deprecated)] let scalar = Scalar::from_bits(clamp_integer(lower)); ExpandedSecretKey { diff --git a/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs b/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs index c9795054c..c519f6931 100644 --- a/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs +++ b/rust-src/concordium_base/src/eddsa_ed25519/dlog_ed25519.rs @@ -67,6 +67,15 @@ fn scalar_from_secret_key(secret_key: &impl AsRef<[u8]>) -> Scalar { h.update(secret_key); hash.copy_from_slice(h.finalize().as_slice()); scalar_bytes.copy_from_slice(&hash[..32]); + + // It seems like `from_bits` is the only way to construct an unreduced scalar + // that can potentially be grater than the field's order. + + // TODO: we use a + // deprecated `from_bits` here, this also requires enabling the + // `legacy_compatibility` feature for the `ed25519-dalek` dependency. Maybe ther + // is a different way of implementing this. + #[allow(deprecated)] Scalar::from_bits(clamp_integer(scalar_bytes)) } diff --git a/rust-src/concordium_base/src/id/account_holder.rs b/rust-src/concordium_base/src/id/account_holder.rs index 990a10c8c..fabfb7ea1 100644 --- a/rust-src/concordium_base/src/id/account_holder.rs +++ b/rust-src/concordium_base/src/id/account_holder.rs @@ -142,7 +142,7 @@ pub fn generate_pio>( let ip_ar_data = ip_ar_data .iter() - .zip(proof.response.r1.r2.responses.into_iter()) + .zip(proof.response.r1.r2.responses) .map(|((ar_id, f), w)| (*ar_id, f(w))) .collect::>(); @@ -216,7 +216,7 @@ pub fn generate_pio_v1>( let ip_ar_data = ip_ar_data .iter() - .zip(proof.response.r2.responses.into_iter()) + .zip(proof.response.r2.responses) .map(|((ar_id, f), w)| (*ar_id, f(w))) .collect::>(); diff --git a/rust-src/concordium_base/src/id/types.rs b/rust-src/concordium_base/src/id/types.rs index b71839dbc..0b5ede72e 100644 --- a/rust-src/concordium_base/src/id/types.rs +++ b/rust-src/concordium_base/src/id/types.rs @@ -2152,9 +2152,7 @@ impl AccountKeys { ( u8::from(*ki), concordium_contracts_common::Signature::Ed25519(SignatureEd25519( - // Unwrap is safe since the conversion is between signature types - // represented by byte arrays of the same length [u8, u64]. - kp.sign(msg).to_bytes().try_into().unwrap(), + kp.sign(msg).to_bytes(), )), ) }) diff --git a/rust-src/concordium_base/src/web3id/mod.rs b/rust-src/concordium_base/src/web3id/mod.rs index 3be1f16f7..03ee72165 100644 --- a/rust-src/concordium_base/src/web3id/mod.rs +++ b/rust-src/concordium_base/src/web3id/mod.rs @@ -494,7 +494,7 @@ impl + serde::de::DeserializeOwned serde_json::from_value(get_field(&mut proof, "proofValue")?)?; anyhow::ensure!(proof_value.len() == statement.len()); - let proofs = statement.into_iter().zip(proof_value.into_iter()).collect(); + let proofs = statement.into_iter().zip(proof_value).collect(); Ok(Self::Account { created, network: issuer.network, @@ -540,7 +540,7 @@ impl + serde::de::DeserializeOwned serde_json::from_value(get_field(&mut proof, "proofValue")?)?; anyhow::ensure!(proof_value.len() == statement.len()); - let proofs = statement.into_iter().zip(proof_value.into_iter()).collect(); + let proofs = statement.into_iter().zip(proof_value).collect(); Ok(Self::Web3Id { created, From 21e8f9c538d9cafe5b09a573ae5f19af28c1a25c Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Fri, 5 Jan 2024 16:03:00 +0100 Subject: [PATCH 17/53] More clippy --- .../src/curve_arithmetic/bls12_381_arkworks.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 242ca82df..9dd70531f 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -87,8 +87,8 @@ impl Serial for Fq12 { c0_6.c2, c0_6.c1, c0_6.c0, ]; for p in coeffs.iter() { - let repr_c1: BigInt<6> = Fq::from(p.c1).into(); - let repr_c0: BigInt<6> = Fq::from(p.c0).into(); + let repr_c1: BigInt<6> = p.c1.into_bigint(); + let repr_c0: BigInt<6> = p.c0.into_bigint(); for d in repr_c1.0.iter() { d.serial(out); } From 9fdc8138b0416067bb1221bd4b9dfd1a5815c536 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 8 Jan 2024 09:51:47 +0100 Subject: [PATCH 18/53] Remove println statements; supress deprecation warning for from_bits() in a test --- rust-src/concordium_base/src/bulletproofs/range_proof.rs | 2 -- .../src/curve_arithmetic/arkworks_instances.rs | 1 - rust-src/concordium_base/src/ecvrf/mod.rs | 7 ++++++- rust-src/concordium_base/src/ecvrf/public.rs | 3 +-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/rust-src/concordium_base/src/bulletproofs/range_proof.rs b/rust-src/concordium_base/src/bulletproofs/range_proof.rs index b8b4e84d0..7ed0239d2 100644 --- a/rust-src/concordium_base/src/bulletproofs/range_proof.rs +++ b/rust-src/concordium_base/src/bulletproofs/range_proof.rs @@ -980,7 +980,6 @@ mod tests { for &v in v_vec.iter().take(m.into()) { let r = Randomness::generate(rng); let v_scalar = SomeCurve::scalar_from_u64(v); - // println!("{:?}", v); let v_value = Value::::new(v_scalar); let com = keys.hide(&v_value, &r); randomness.push(r); @@ -998,7 +997,6 @@ mod tests { &keys, &randomness, ); - println!("{:?}", proof); assert!(proof.is_some()); let proof = proof.unwrap(); let mut transcript = RandomOracle::empty(); diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index a06ac632c..8672153fa 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -183,7 +183,6 @@ where for chunk in bs.as_ref().chunks(8).take(s as usize) { let mut v = [0u8; 8]; v[..chunk.len()].copy_from_slice(chunk); - println!("{:?}", v); fr.push(u64::from_le_bytes(v)); } // unset two topmost bits in the last read u64. diff --git a/rust-src/concordium_base/src/ecvrf/mod.rs b/rust-src/concordium_base/src/ecvrf/mod.rs index 2da0fae6f..99555959a 100644 --- a/rust-src/concordium_base/src/ecvrf/mod.rs +++ b/rust-src/concordium_base/src/ecvrf/mod.rs @@ -262,7 +262,12 @@ mod tests { // Test serialization of generated secret scalar let x = expanded_sk.key; - assert_eq!(x, Scalar::from_bits(x_bytes)); + // TODO: we use deprecated `from_bits` here, this also requires enabling the + // `legacy_compatibility` feature for the `ed25519-dalek` dependency. Maybe ther + // is a different way of implementing this. + #[allow(deprecated)] + let scalar = Scalar::from_bits(x_bytes); + assert_eq!(x, scalar); // Test serialization of proof let proof = expanded_sk.prove(&pk, &alpha_bytes); diff --git a/rust-src/concordium_base/src/ecvrf/public.rs b/rust-src/concordium_base/src/ecvrf/public.rs index bd03b93d7..53ad0614a 100644 --- a/rust-src/concordium_base/src/ecvrf/public.rs +++ b/rust-src/concordium_base/src/ecvrf/public.rs @@ -97,8 +97,7 @@ impl PublicKey { // It seems like `from_bits` is the only way to construct an unreduced scalar // that can potentially be grater than the field's order. - // TODO: we use a - // deprecated `from_bits` here, this also requires enabling the + // TODO: we use deprecated `from_bits` here, this also requires enabling the // `legacy_compatibility` feature for the `ed25519-dalek` dependency. Maybe ther // is a different way of implementing this. #[allow(deprecated)] From c05f4ec09024a4e3ab67d2e4b67fe2be4d33d3dd Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 8 Jan 2024 13:54:58 +0100 Subject: [PATCH 19/53] Fix signatures of ed25519 sign functions on the Haskell side --- haskell-src/Concordium/Crypto/BlockSignature.hs | 2 +- haskell-src/Concordium/Crypto/Ed25519Signature.hs | 15 +++++++-------- haskell-src/Concordium/Crypto/SignatureScheme.hs | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/haskell-src/Concordium/Crypto/BlockSignature.hs b/haskell-src/Concordium/Crypto/BlockSignature.hs index b137de608..bf06a99e8 100644 --- a/haskell-src/Concordium/Crypto/BlockSignature.hs +++ b/haskell-src/Concordium/Crypto/BlockSignature.hs @@ -51,7 +51,7 @@ signatureLength :: Int signatureLength = Ed25519.signatureSize sign :: KeyPair -> ByteString -> Signature -sign KeyPair{..} = Signature . Ed25519.sign signKey verifyKey +sign KeyPair{..} = Signature . Ed25519.sign signKey verify :: VerifyKey -> ByteString -> Signature -> Bool verify vfKey bs (Signature s) = Ed25519.verify vfKey bs s diff --git a/haskell-src/Concordium/Crypto/Ed25519Signature.hs b/haskell-src/Concordium/Crypto/Ed25519Signature.hs index bd6b05b47..47bb10a92 100644 --- a/haskell-src/Concordium/Crypto/Ed25519Signature.hs +++ b/haskell-src/Concordium/Crypto/Ed25519Signature.hs @@ -122,15 +122,14 @@ newKeyPair = do let verifyKey = deriveVerifyKey signKey return (signKey, verifyKey) -sign :: SignKey -> VerifyKey -> ByteString -> BSS.ShortByteString -sign signKey verifyKey m = unsafePerformIO $ +sign :: SignKey -> ByteString -> BSS.ShortByteString +sign signKey m = unsafePerformIO $ withSignKey signKey $ \signKeyPtr -> - withVerifyKey verifyKey $ \verifyKeyPtr -> - BS.unsafeUseAsCStringLen m $ \(m', mlen) -> do - -- this use of unsafe is fine because the sign function - -- checks the length before dereferencing the data pointer - ((), s) <- withAllocatedShortByteString signatureSize $ signFFI (castPtr m') (fromIntegral mlen) signKeyPtr verifyKeyPtr - return s + BS.unsafeUseAsCStringLen m $ \(m', mlen) -> do + -- this use of unsafe is fine because the sign function + -- checks the length before dereferencing the data pointer + ((), s) <- withAllocatedShortByteString signatureSize $ signFFI (castPtr m') (fromIntegral mlen) signKeyPtr + return s verify :: VerifyKey -> ByteString -> BSS.ShortByteString -> Bool verify vf m sig = (BSS.length sig == signatureSize) && (suc > 0) diff --git a/haskell-src/Concordium/Crypto/SignatureScheme.hs b/haskell-src/Concordium/Crypto/SignatureScheme.hs index 680e77b2f..944d35cba 100644 --- a/haskell-src/Concordium/Crypto/SignatureScheme.hs +++ b/haskell-src/Concordium/Crypto/SignatureScheme.hs @@ -142,7 +142,7 @@ toScheme n | otherwise = Nothing sign :: KeyPair -> ByteString -> Signature -sign KeyPairEd25519{..} = Signature . Ed25519.sign signKey verifyKey +sign KeyPairEd25519{..} = Signature . Ed25519.sign signKey verify :: VerifyKey -> ByteString -> Signature -> Bool verify (VerifyKeyEd25519 vfKey) bs (Signature s) = Ed25519.verify vfKey bs s From a063936c8df10d4380c9f88877a244e7ac34344a Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 8 Jan 2024 13:58:16 +0100 Subject: [PATCH 20/53] Remove redundant imports in ffi --- rust-src/concordium_base/src/aggregate_sig/ffi.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/rust-src/concordium_base/src/aggregate_sig/ffi.rs b/rust-src/concordium_base/src/aggregate_sig/ffi.rs index 3d4be223a..8ec079000 100644 --- a/rust-src/concordium_base/src/aggregate_sig/ffi.rs +++ b/rust-src/concordium_base/src/aggregate_sig/ffi.rs @@ -1,10 +1,7 @@ #![cfg(feature = "ffi")] use super::*; -use crate::{ - common::*, curve_arithmetic::arkworks_instances::ArkGroup, ffi_helpers::*, - random_oracle::RandomOracle, sigma_protocols::dlog, -}; +use crate::{common::*, ffi_helpers::*, random_oracle::RandomOracle, sigma_protocols::dlog}; use rand::{rngs::StdRng, thread_rng, SeedableRng}; use std::{cmp::Ordering, slice}; From 3988bfadaabc23413f49180c383fb2bd94e91f8e Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 8 Jan 2024 14:49:49 +0100 Subject: [PATCH 21/53] Fix benchmark --- rust-src/concordium_base/benches/compute_message.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rust-src/concordium_base/benches/compute_message.rs b/rust-src/concordium_base/benches/compute_message.rs index 3c8655228..8ce5f8554 100644 --- a/rust-src/concordium_base/benches/compute_message.rs +++ b/rust-src/concordium_base/benches/compute_message.rs @@ -1,6 +1,7 @@ +use ark_bls12_381::G1Projective; use concordium_base::{ common::types::*, - curve_arithmetic::*, + curve_arithmetic::{*, arkworks_instances::ArkGroup}, id, id::{ constants::*, @@ -13,7 +14,6 @@ use concordium_base::{ ps_sig, }; use criterion::*; -use pairing::bls12_381::{G1, *}; use rand::*; use serde_json::from_str; use std::{ @@ -21,6 +21,9 @@ use std::{ convert::TryFrom, }; +type G1 = ArkGroup; +type Bls12 = ark_ec::bls12::Bls12; + fn bench_compute_message(c: &mut Criterion) { let mut csprng = thread_rng(); From 55606a8d30d9bd13b35545ef9023d607e1e38b85 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 8 Jan 2024 16:54:49 +0100 Subject: [PATCH 22/53] Rust formatting --- rust-src/concordium_base/benches/compute_message.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-src/concordium_base/benches/compute_message.rs b/rust-src/concordium_base/benches/compute_message.rs index 8ce5f8554..012faede9 100644 --- a/rust-src/concordium_base/benches/compute_message.rs +++ b/rust-src/concordium_base/benches/compute_message.rs @@ -1,7 +1,7 @@ use ark_bls12_381::G1Projective; use concordium_base::{ common::types::*, - curve_arithmetic::{*, arkworks_instances::ArkGroup}, + curve_arithmetic::{arkworks_instances::ArkGroup, *}, id, id::{ constants::*, From 9448367fe6656c27b07ff023dfa141f774121d10 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Tue, 9 Jan 2024 15:26:51 +0100 Subject: [PATCH 23/53] Update Cargo.lock --- mobile_wallet/Cargo.lock | 53 +++++----------------------------- rust-bins/Cargo.lock | 53 +++++----------------------------- rust-src/Cargo.lock | 53 +++++----------------------------- rust-src/keygen_bls/Cargo.toml | 1 - 4 files changed, 21 insertions(+), 139 deletions(-) diff --git a/mobile_wallet/Cargo.lock b/mobile_wallet/Cargo.lock index 2fda3ee4c..662d14630 100644 --- a/mobile_wallet/Cargo.lock +++ b/mobile_wallet/Cargo.lock @@ -91,7 +91,7 @@ dependencies = [ "derivative", "digest 0.10.6", "itertools", - "num-bigint 0.4.3", + "num-bigint", "num-traits", "paste", "rustc_version", @@ -114,7 +114,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint 0.4.3", + "num-bigint", "num-traits", "proc-macro2", "quote", @@ -143,7 +143,7 @@ dependencies = [ "ark-serialize-derive", "ark-std", "digest 0.10.6", - "num-bigint 0.4.3", + "num-bigint", ] [[package]] @@ -389,7 +389,7 @@ dependencies = [ "fnv", "hashbrown 0.11.2", "hex", - "num-bigint 0.4.3", + "num-bigint", "num-integer", "num-traits", "rust_decimal", @@ -434,7 +434,7 @@ dependencies = [ "libc", "nom", "num", - "num-bigint 0.4.3", + "num-bigint", "num-traits", "rand 0.8.5", "rayon", @@ -761,7 +761,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4530da57967e140ee0b44e0143aa66b5cb42bd9c503dbe316a15d5b0be65713e" dependencies = [ "byteorder", - "ff_derive", "rand_core 0.5.1", ] @@ -776,20 +775,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ff_derive" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5796e7d62ca01a00ed3a649b0da1ffa1ac8f06bcad40339df09dbdd69a05ba9" -dependencies = [ - "num-bigint 0.2.6", - "num-integer", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "fiat-crypto" version = "0.2.5" @@ -1037,7 +1022,6 @@ dependencies = [ "ff 0.5.2", "hex", "hkdf", - "pairing", "sha2 0.10.6", ] @@ -1133,7 +1117,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" dependencies = [ - "num-bigint 0.4.3", + "num-bigint", "num-complex", "num-integer", "num-iter", @@ -1141,17 +1125,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-bigint" version = "0.4.3" @@ -1200,7 +1173,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", - "num-bigint 0.4.3", + "num-bigint", "num-integer", "num-traits", ] @@ -1236,18 +1209,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "pairing" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c40534479a28199cd5109da27fe2fc4a4728e4fc701d9e9c1bded78f3271e4" -dependencies = [ - "byteorder", - "ff 0.5.2", - "group 0.2.0", - "rand_core 0.5.1", -] - [[package]] name = "password-hash" version = "0.3.2" diff --git a/rust-bins/Cargo.lock b/rust-bins/Cargo.lock index 918d9a9b0..506fec320 100644 --- a/rust-bins/Cargo.lock +++ b/rust-bins/Cargo.lock @@ -131,7 +131,7 @@ dependencies = [ "derivative", "digest 0.10.7", "itertools", - "num-bigint 0.4.4", + "num-bigint", "num-traits", "paste", "rustc_version", @@ -154,7 +154,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint 0.4.4", + "num-bigint", "num-traits", "proc-macro2", "quote", @@ -183,7 +183,7 @@ dependencies = [ "ark-serialize-derive", "ark-std", "digest 0.10.7", - "num-bigint 0.4.4", + "num-bigint", ] [[package]] @@ -477,7 +477,7 @@ dependencies = [ "fnv", "hashbrown 0.11.2", "hex", - "num-bigint 0.4.4", + "num-bigint", "num-integer", "num-traits", "rust_decimal", @@ -526,7 +526,7 @@ dependencies = [ "libc", "nom", "num", - "num-bigint 0.4.4", + "num-bigint", "num-traits", "pbkdf2 0.11.0", "rand 0.8.5", @@ -908,7 +908,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4530da57967e140ee0b44e0143aa66b5cb42bd9c503dbe316a15d5b0be65713e" dependencies = [ "byteorder", - "ff_derive", "rand_core 0.5.1", ] @@ -923,20 +922,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ff_derive" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5796e7d62ca01a00ed3a649b0da1ffa1ac8f06bcad40339df09dbdd69a05ba9" -dependencies = [ - "num-bigint 0.2.6", - "num-integer", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "fiat-crypto" version = "0.2.1" @@ -1398,7 +1383,6 @@ dependencies = [ "ff 0.5.2", "hex", "hkdf", - "pairing", "sha2 0.10.8", ] @@ -1591,7 +1575,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" dependencies = [ - "num-bigint 0.4.4", + "num-bigint", "num-complex", "num-integer", "num-iter", @@ -1599,17 +1583,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-bigint" version = "0.4.4" @@ -1658,7 +1631,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", - "num-bigint 0.4.4", + "num-bigint", "num-integer", "num-traits", ] @@ -1757,18 +1730,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "pairing" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c40534479a28199cd5109da27fe2fc4a4728e4fc701d9e9c1bded78f3271e4" -dependencies = [ - "byteorder", - "ff 0.5.2", - "group 0.2.0", - "rand_core 0.5.1", -] - [[package]] name = "parking_lot" version = "0.11.2" diff --git a/rust-src/Cargo.lock b/rust-src/Cargo.lock index eadd7e3db..435341f22 100644 --- a/rust-src/Cargo.lock +++ b/rust-src/Cargo.lock @@ -113,7 +113,7 @@ dependencies = [ "derivative", "digest 0.10.7", "itertools", - "num-bigint 0.4.4", + "num-bigint", "num-traits", "paste", "rustc_version", @@ -136,7 +136,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint 0.4.4", + "num-bigint", "num-traits", "proc-macro2", "quote", @@ -165,7 +165,7 @@ dependencies = [ "ark-serialize-derive", "ark-std", "digest 0.10.7", - "num-bigint 0.4.4", + "num-bigint", ] [[package]] @@ -477,7 +477,7 @@ dependencies = [ "fnv", "hashbrown 0.11.2", "hex", - "num-bigint 0.4.4", + "num-bigint", "num-integer", "num-traits", "rust_decimal", @@ -527,7 +527,7 @@ dependencies = [ "libc", "nom", "num", - "num-bigint 0.4.4", + "num-bigint", "num-traits", "pbkdf2 0.11.0", "rand 0.8.5", @@ -852,7 +852,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4530da57967e140ee0b44e0143aa66b5cb42bd9c503dbe316a15d5b0be65713e" dependencies = [ "byteorder", - "ff_derive", "rand_core 0.5.1", ] @@ -867,20 +866,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ff_derive" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5796e7d62ca01a00ed3a649b0da1ffa1ac8f06bcad40339df09dbdd69a05ba9" -dependencies = [ - "num-bigint 0.2.6", - "num-integer", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "fiat-crypto" version = "0.2.1" @@ -1147,7 +1132,6 @@ dependencies = [ "ff 0.5.2", "hex", "hkdf", - "pairing", "sha2 0.10.7", ] @@ -1212,7 +1196,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" dependencies = [ - "num-bigint 0.4.4", + "num-bigint", "num-complex", "num-integer", "num-iter", @@ -1220,17 +1204,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-bigint" version = "0.4.4" @@ -1279,7 +1252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", - "num-bigint 0.4.4", + "num-bigint", "num-integer", "num-traits", ] @@ -1327,18 +1300,6 @@ version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" -[[package]] -name = "pairing" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c40534479a28199cd5109da27fe2fc4a4728e4fc701d9e9c1bded78f3271e4" -dependencies = [ - "byteorder", - "ff 0.5.2", - "group 0.2.0", - "rand_core 0.5.1", -] - [[package]] name = "password-hash" version = "0.3.2" diff --git a/rust-src/keygen_bls/Cargo.toml b/rust-src/keygen_bls/Cargo.toml index 1c9d7d399..7a8615772 100644 --- a/rust-src/keygen_bls/Cargo.toml +++ b/rust-src/keygen_bls/Cargo.toml @@ -6,7 +6,6 @@ edition = "2018" license-file = "../../LICENSE" [dependencies] -pairing = "0.15" sha2 = "0.10" hkdf = "0.12.0" ff = "0.5" From 8b6dc4632a61415c8b87bb9969d0f8a214c414c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Bizjak?= Date: Wed, 10 Jan 2024 10:20:44 +0100 Subject: [PATCH 24/53] Remove the use of from_bits. --- rust-src/concordium_base/src/ecvrf/mod.rs | 2 +- rust-src/concordium_base/src/ecvrf/public.rs | 37 +++++--------------- rust-src/concordium_base/src/ecvrf/secret.rs | 2 +- 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/rust-src/concordium_base/src/ecvrf/mod.rs b/rust-src/concordium_base/src/ecvrf/mod.rs index 2da0fae6f..c365b3518 100644 --- a/rust-src/concordium_base/src/ecvrf/mod.rs +++ b/rust-src/concordium_base/src/ecvrf/mod.rs @@ -262,7 +262,7 @@ mod tests { // Test serialization of generated secret scalar let x = expanded_sk.key; - assert_eq!(x, Scalar::from_bits(x_bytes)); + assert_eq!(x, Scalar::from_bytes_mod_order(x_bytes)); // Test serialization of proof let proof = expanded_sk.prove(&pk, &alpha_bytes); diff --git a/rust-src/concordium_base/src/ecvrf/public.rs b/rust-src/concordium_base/src/ecvrf/public.rs index bbb84a62d..869377ef7 100644 --- a/rust-src/concordium_base/src/ecvrf/public.rs +++ b/rust-src/concordium_base/src/ecvrf/public.rs @@ -61,25 +61,20 @@ impl From<&SecretKey> for PublicKey { /// Derive this public key from its corresponding `SecretKey`. /// Implements fn from(secret_key: &SecretKey) -> PublicKey { - let mut h: Sha512 = Sha512::new(); - let mut hash: [u8; 64] = [0u8; 64]; - let mut digest: [u8; 32] = [0u8; 32]; - - h.update(secret_key.as_bytes()); - hash.copy_from_slice(h.finalize().as_slice()); - - digest.copy_from_slice(&hash[..32]); - - PublicKey::mangle_scalar_bits_and_multiply_by_basepoint_to_produce_public_key(&mut digest) + let expanded = ExpandedSecretKey::from(secret_key); + (&expanded).into() } } impl From<&ExpandedSecretKey> for PublicKey { /// Derive this public key from its corresponding `ExpandedSecretKey`. fn from(expanded_secret_key: &ExpandedSecretKey) -> PublicKey { - let mut bits: [u8; 32] = expanded_secret_key.key.to_bytes(); + let key = expanded_secret_key.key; + + let point = &key * &constants::ED25519_BASEPOINT_TABLE; + let compressed = point.compress(); - PublicKey::mangle_scalar_bits_and_multiply_by_basepoint_to_produce_public_key(&mut bits) + PublicKey(compressed, point) } } @@ -88,22 +83,6 @@ impl PublicKey { #[inline] pub fn as_bytes(&self) -> &'_ [u8; PUBLIC_KEY_LENGTH] { &(self.0).0 } - /// Internal utility function for mangling the bits of a (formerly - /// mathematically well-defined) "scalar" and multiplying it to produce a - /// public key. - fn mangle_scalar_bits_and_multiply_by_basepoint_to_produce_public_key( - bits: &mut [u8; 32], - ) -> PublicKey { - bits[0] &= 0b_1111_1000; - bits[31] &= 0b_0111_1111; - bits[31] |= 0b_0100_0000; - - let point = &Scalar::from_bits(*bits) * &constants::ED25519_BASEPOINT_TABLE; - let compressed = point.compress(); - - PublicKey(compressed, point) - } - /// Implements /// The failure should not happen in practice, expected number of iterations /// is 2. @@ -115,7 +94,7 @@ impl PublicKey { h.update(self.as_bytes()); // PK_string h.update(message); // alpha_string for ctr in 0..=u8::max_value() { - // Each iteration fails, indpendent of other iterations, with probability about + // Each iteration fails, independent of other iterations, with probability about // a half. This happens if the digest does not represent a point on // the curve when decoded as in https://tools.ietf.org/html/rfc8032#section-5.1.3 let mut attempt_h = h.clone(); diff --git a/rust-src/concordium_base/src/ecvrf/secret.rs b/rust-src/concordium_base/src/ecvrf/secret.rs index 633e78912..3d40b5389 100644 --- a/rust-src/concordium_base/src/ecvrf/secret.rs +++ b/rust-src/concordium_base/src/ecvrf/secret.rs @@ -128,7 +128,7 @@ impl From<&SecretKey> for ExpandedSecretKey { lower[31] |= 0b_0100_0000; ExpandedSecretKey { - key: Scalar::from_bits(lower), + key: Scalar::from_bytes_mod_order(lower), nonce: upper, } } From 5e22e5c3acc7b6aa225097044209f6e303072420 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Wed, 10 Jan 2024 15:54:05 +0100 Subject: [PATCH 25/53] Fix links to the VRF RFC --- rust-src/concordium_base/src/ecvrf/proof.rs | 6 +++--- rust-src/concordium_base/src/ecvrf/public.rs | 6 ++++-- rust-src/concordium_base/src/ecvrf/secret.rs | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/rust-src/concordium_base/src/ecvrf/proof.rs b/rust-src/concordium_base/src/ecvrf/proof.rs index 4db65346f..6b4368fa0 100644 --- a/rust-src/concordium_base/src/ecvrf/proof.rs +++ b/rust-src/concordium_base/src/ecvrf/proof.rs @@ -29,7 +29,7 @@ pub fn hash_points(pts: &[CompressedEdwardsY]) -> Scalar { /// a given public key. pub struct Proof(pub EdwardsPoint, pub Scalar, pub Scalar); -/// Implements step 8 of +/// Implements step 8 of /// i.e. transforms a proof to a byte string impl Serial for Proof { #[inline] @@ -48,7 +48,7 @@ impl Serial for Proof { } } -/// Implements +/// Implements /// Construct a `Proof` from a slice of bytes. This function always /// results in a valid proof object. impl Deserial for Proof { @@ -80,7 +80,7 @@ impl Debug for Proof { } } -/// Implements +/// Implements impl Proof { pub fn to_hash(&self) -> [u8; 64] { let p = self.0.mul_by_cofactor(); diff --git a/rust-src/concordium_base/src/ecvrf/public.rs b/rust-src/concordium_base/src/ecvrf/public.rs index 9017e148e..abafbbd0d 100644 --- a/rust-src/concordium_base/src/ecvrf/public.rs +++ b/rust-src/concordium_base/src/ecvrf/public.rs @@ -82,9 +82,11 @@ impl PublicKey { #[inline] pub fn as_bytes(&self) -> &'_ [u8; PUBLIC_KEY_LENGTH] { &(self.0).0 } - /// Implements + /// Implements /// The failure should not happen in practice, expected number of iterations /// is 2. + // TODO: Check whether it still implements the algorithm after the RFC draft was + // converted to a "stable" RFC version. pub fn hash_to_curve(&self, message: &[u8]) -> Option { let mut p_candidate_bytes = [0u8; 32]; let mut h: Sha512 = Sha512::new(); @@ -115,7 +117,7 @@ impl PublicKey { pub fn verify_key(&self) -> bool { !self.1.is_small_order() } - /// Implements + /// Implements #[allow(clippy::many_single_char_names)] pub fn verify(&self, pi: &Proof, message: &[u8]) -> bool { if let Some(h) = self.hash_to_curve(message) { diff --git a/rust-src/concordium_base/src/ecvrf/secret.rs b/rust-src/concordium_base/src/ecvrf/secret.rs index 93b346944..7b5a10349 100644 --- a/rust-src/concordium_base/src/ecvrf/secret.rs +++ b/rust-src/concordium_base/src/ecvrf/secret.rs @@ -136,7 +136,7 @@ use super::proof::*; impl ExpandedSecretKey { /// VRF proof with expanded secret key - /// Implements + /// Implements pub fn prove(&self, public_key: &PublicKey, alpha: &[u8]) -> Proof { let x = self.key; let h = public_key @@ -159,7 +159,7 @@ impl ExpandedSecretKey { Proof(gamma, c, k_plus_cx) } - /// Implements + /// Implements fn nonce_generation(&self, h_string: &[u8]) -> Scalar { let digest = Sha512::new() .chain_update(self.nonce) From 023a9f9ddf578d24914368b2555d50426e581b99 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 11 Jan 2024 15:49:56 +0100 Subject: [PATCH 26/53] Fixes after review: use ArCurve and IpPairing to avoid dependency on arkworks; add ArCurveG2 public type alias for the G2 group on bls --- idiss/Cargo.lock | 2 -- idiss/Cargo.toml | 2 -- idiss/src/lib.rs | 9 ++++---- mobile_wallet/Cargo.lock | 2 -- mobile_wallet/Cargo.toml | 2 -- mobile_wallet/src/lib.rs | 4 ++-- rust-bins/Cargo.lock | 3 --- rust-bins/Cargo.toml | 4 +--- rust-bins/src/bin/client.rs | 8 +++---- rust-bins/src/bin/generate_testdata.rs | 7 +++---- rust-bins/src/bin/identity_provider_cli.rs | 2 +- rust-bins/src/bin/keygen-genesis.rs | 14 +++++++------ rust-bins/src/bin/keygen.rs | 21 +++++++++---------- rust-bins/src/lib.rs | 2 +- .../benches/elgamal_benchmarks.rs | 5 +++-- .../curve_arithmetic/bls12_381_arkworks.rs | 6 ++++-- rust-src/concordium_base/src/id/constants.rs | 12 ++++++----- .../src/sigma_protocols/com_ineq.rs | 7 +++---- .../src/sigma_protocols/com_lin.rs | 7 +++---- .../src/sigma_protocols/dlogaggequal.rs | 10 ++++----- .../src/sigma_protocols/dlogeq.rs | 11 +++++----- 21 files changed, 63 insertions(+), 77 deletions(-) diff --git a/idiss/Cargo.lock b/idiss/Cargo.lock index 35f26bc4b..40a23b057 100644 --- a/idiss/Cargo.lock +++ b/idiss/Cargo.lock @@ -946,8 +946,6 @@ name = "idiss" version = "0.7.0" dependencies = [ "anyhow", - "ark-bls12-381", - "ark-ec", "byteorder", "chrono", "concordium_base", diff --git a/idiss/Cargo.toml b/idiss/Cargo.toml index 2bf676c3b..7507abedf 100644 --- a/idiss/Cargo.toml +++ b/idiss/Cargo.toml @@ -32,8 +32,6 @@ serde_json = "1.0" chrono = "0.4.24" # the patch version is necessary since chrono adds new functionality in patch versions ed25519-dalek = "2.0" byteorder = "1.3" -ark-bls12-381 = { version = "0.4"} -ark-ec = { version = "0.4"} [dependencies.nodejs-sys] version = "0.12.0" diff --git a/idiss/src/lib.rs b/idiss/src/lib.rs index 7cf9385c3..57051d529 100644 --- a/idiss/src/lib.rs +++ b/idiss/src/lib.rs @@ -1,11 +1,10 @@ use anyhow::Context; -use ark_bls12_381::G1Projective; use concordium_base::{ common::{base16_decode_string, types::TransactionTime, Versioned, VERSION_0}, - curve_arithmetic::{arkworks_instances::ArkGroup, *}, + curve_arithmetic::*, id, id::{ - constants::{ArCurve, AttributeKind}, + constants::{ArCurve, AttributeKind, IpPairing}, identity_provider::{ create_initial_cdi, sign_identity_object, sign_identity_object_v1, validate_id_recovery_request, validate_request as ip_validate_request, @@ -19,8 +18,8 @@ use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize}; #[cfg(feature = "nodejs")] use serde_json::ser::to_string; -type Bls12 = ark_ec::bls12::Bls12; -type G1 = ArkGroup; +type Bls12 = IpPairing; +type G1 = ArCurve; type ExampleCurve = G1; type ExampleAttributeList = AttributeList<::ScalarField, AttributeKind>; diff --git a/mobile_wallet/Cargo.lock b/mobile_wallet/Cargo.lock index 662d14630..295877a5a 100644 --- a/mobile_wallet/Cargo.lock +++ b/mobile_wallet/Cargo.lock @@ -1081,8 +1081,6 @@ name = "mobile_wallet" version = "0.25.1" dependencies = [ "anyhow", - "ark-bls12-381", - "ark-ec", "base64", "byteorder", "chrono", diff --git a/mobile_wallet/Cargo.toml b/mobile_wallet/Cargo.toml index 1de7068de..be96f642a 100644 --- a/mobile_wallet/Cargo.toml +++ b/mobile_wallet/Cargo.toml @@ -21,8 +21,6 @@ sha2 = "0.10" libc = "0.2" thiserror = "1.0" base64 = "0.21" -ark-bls12-381 = { version = "0.4"} -ark-ec = { version = "0.4"} [dependencies.key_derivation] path = "../rust-src/key_derivation" diff --git a/mobile_wallet/src/lib.rs b/mobile_wallet/src/lib.rs index b03df6fd6..8cb7be7bc 100644 --- a/mobile_wallet/src/lib.rs +++ b/mobile_wallet/src/lib.rs @@ -15,7 +15,7 @@ use concordium_base::{ hashes::{HashBytes, TransactionSignHash}, id::{ self, account_holder, - constants::{ArCurve, AttributeKind}, + constants::{ArCurve, AttributeKind, IpPairing}, id_proof_types::{ProofVersion, Statement, StatementWithContext}, pedersen_commitment::Value as PedersenValue, ps_sig, @@ -45,7 +45,7 @@ use std::{ str::FromStr, }; -type Bls12 = ark_ec::bls12::Bls12; +type Bls12 = IpPairing; /// Context for a transaction to send. #[derive(common::SerdeDeserialize)] diff --git a/rust-bins/Cargo.lock b/rust-bins/Cargo.lock index 506fec320..f288c54c9 100644 --- a/rust-bins/Cargo.lock +++ b/rust-bins/Cargo.lock @@ -817,7 +817,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" dependencies = [ "pkcs8", - "serde", "signature", ] @@ -1501,8 +1500,6 @@ version = "2.0.2" dependencies = [ "aes", "anyhow", - "ark-bls12-381", - "ark-ec", "base64", "bitvec", "chrono", diff --git a/rust-bins/Cargo.toml b/rust-bins/Cargo.toml index b3603333e..598c43ef8 100644 --- a/rust-bins/Cargo.toml +++ b/rust-bins/Cargo.toml @@ -16,7 +16,7 @@ dialoguer = "0.10" rand = "=0.8" serde = "1.0" serde_json = "1.0" -ed25519-dalek = { version = "2.0", features = ["serde"]} +ed25519-dalek = {version = "2.0"} curve25519-dalek = "4.0" structopt = "0.3" hex = "0.4" @@ -36,8 +36,6 @@ rpassword = "6.0" bitvec = "1" crossterm = "0.22" anyhow = "1.0" -ark-bls12-381 = { version = "0.4"} -ark-ec = { version = "0.4"} [dependencies.ed25519_hd_key_derivation] path = "../rust-src/ed25519_hd_key_derivation" diff --git a/rust-bins/src/bin/client.rs b/rust-bins/src/bin/client.rs index 8f7060276..61afc4660 100644 --- a/rust-bins/src/bin/client.rs +++ b/rust-bins/src/bin/client.rs @@ -1,4 +1,3 @@ -use ark_bls12_381::G1Projective; use clap::AppSettings; use client_server_helpers::*; use concordium_base::{ @@ -6,7 +5,6 @@ use concordium_base::{ types::{Amount, CredentialIndex, KeyIndex, KeyPair, TransactionTime}, *, }, - curve_arithmetic::arkworks_instances::ArkGroup, dodis_yampolskiy_prf as prf, elgamal::{self, PublicKey, SecretKey}, id::{ @@ -24,7 +22,7 @@ use concordium_base::{ use dialoguer::{Input, MultiSelect, Select}; use ed25519_dalek as ed25519; use either::Either::{Left, Right}; -use key_derivation::{words_to_seed, ConcordiumHdWallet, CredentialContext, Net}; +use key_derivation::{ConcordiumHdWallet, CredentialContext, Net}; use rand::*; use serde_json::{json, to_value}; use std::{ @@ -37,8 +35,8 @@ use std::{ }; use structopt::StructOpt; -type Bls12 = ark_ec::bls12::Bls12; -type G1 = ArkGroup; +type Bls12 = IpPairing; +type G1 = ArCurve; static IP_NAME_PREFIX: &str = "identity_provider-"; static AR_NAME_PREFIX: &str = "AR-"; diff --git a/rust-bins/src/bin/generate_testdata.rs b/rust-bins/src/bin/generate_testdata.rs index daf49a1a9..087451412 100644 --- a/rust-bins/src/bin/generate_testdata.rs +++ b/rust-bins/src/bin/generate_testdata.rs @@ -1,4 +1,3 @@ -use ark_bls12_381::G1Projective; use clap::AppSettings; use client_server_helpers::*; use concordium_base::{ @@ -6,7 +5,7 @@ use concordium_base::{ types::{KeyIndex, KeyPair, TransactionTime}, *, }, - curve_arithmetic::{arkworks_instances::ArkGroup, Curve, Pairing}, + curve_arithmetic::{Curve, Pairing}, dodis_yampolskiy_prf as prf, id::{ account_holder::*, @@ -22,8 +21,8 @@ use rand::*; use std::{collections::btree_map::BTreeMap, fs::File, io::Write, path::PathBuf}; use structopt::StructOpt; -type Bls12 = ark_ec::bls12::Bls12; -type G1 = ArkGroup; +type Bls12 = IpPairing; +type G1 = ArCurve; type ExampleAttribute = AttributeKind; diff --git a/rust-bins/src/bin/identity_provider_cli.rs b/rust-bins/src/bin/identity_provider_cli.rs index b5798661a..7e18175e7 100644 --- a/rust-bins/src/bin/identity_provider_cli.rs +++ b/rust-bins/src/bin/identity_provider_cli.rs @@ -14,7 +14,7 @@ use dialoguer::Input; use std::{collections::btree_map::BTreeMap, path::PathBuf}; use structopt::StructOpt; -type Bls12 = ark_ec::bls12::Bls12; +type Bls12 = IpPairing; #[derive(StructOpt)] #[structopt( diff --git a/rust-bins/src/bin/keygen-genesis.rs b/rust-bins/src/bin/keygen-genesis.rs index d3c79b67a..f1bf345e7 100644 --- a/rust-bins/src/bin/keygen-genesis.rs +++ b/rust-bins/src/bin/keygen-genesis.rs @@ -1,11 +1,13 @@ -use ark_bls12_381::{G1Projective, G2Projective}; use clap::AppSettings; use client_server_helpers::*; use concordium_base::{ common::*, - curve_arithmetic::{arkworks_instances::ArkGroup, Curve}, + curve_arithmetic::Curve, elgamal::PublicKey, - id::types::*, + id::{ + constants::{ArCurve, ArCurveG2, IpPairing}, + types::*, + }, ps_sig, }; use curve25519_dalek::edwards::CompressedEdwardsY; @@ -13,9 +15,9 @@ use sha2::{Digest, Sha512}; use std::{fs, path::PathBuf}; use structopt::StructOpt; -type Bls12 = ark_ec::bls12::Bls12; -type G1 = ArkGroup; -type G2 = ArkGroup; +type Bls12 = IpPairing; +type G1 = ArCurve; +type G2 = ArCurveG2; #[derive(StructOpt)] struct KeygenIp { diff --git a/rust-bins/src/bin/keygen.rs b/rust-bins/src/bin/keygen.rs index 5ac920791..b049b11f2 100644 --- a/rust-bins/src/bin/keygen.rs +++ b/rust-bins/src/bin/keygen.rs @@ -1,14 +1,13 @@ -use ark_bls12_381::{G1Projective, G2Projective}; use clap::AppSettings; use client_server_helpers::*; use concordium_base::{ common::*, - curve_arithmetic::{ - arkworks_instances::{ArkField, ArkGroup}, - Curve, - }, + curve_arithmetic::Curve, elgamal::{PublicKey, SecretKey}, - id::types::*, + id::{ + constants::{ArCurve, ArCurveG2, BaseField, IpPairing}, + types::*, + }, ps_sig, }; use crossterm::{ @@ -29,10 +28,10 @@ use std::{ }; use structopt::StructOpt; -type Bls12 = ark_ec::bls12::Bls12; -type G1 = ArkGroup; -type G2 = ArkGroup; -type Fr = ArkField; +type Bls12 = IpPairing; +type G1 = ArCurve; +type G2 = ArCurveG2; +type Fr = BaseField; const BIP39_ENGLISH: &str = include_str!("data/BIP39English.txt"); @@ -311,7 +310,7 @@ fn handle_generate_update_keys(kgup: KeygenGovernance) -> Result<(), String> { "verifyKey": base16_encode_string(&signing_key.verifying_key()), "scheme": "Ed25519", }, - "signature": sig, + "signature": base16_encode_string(&sig), "type": level_str, }); let secret_data = serde_json::json!({ diff --git a/rust-bins/src/lib.rs b/rust-bins/src/lib.rs index da17abe94..4b7de1a82 100644 --- a/rust-bins/src/lib.rs +++ b/rust-bins/src/lib.rs @@ -20,7 +20,7 @@ use std::{ str::FromStr, }; -type Bls12 = ark_ec::bls12::Bls12; +type Bls12 = IpPairing; pub type ExampleAttribute = AttributeKind; diff --git a/rust-src/concordium_base/benches/elgamal_benchmarks.rs b/rust-src/concordium_base/benches/elgamal_benchmarks.rs index 6481109f8..0bb433ab6 100644 --- a/rust-src/concordium_base/benches/elgamal_benchmarks.rs +++ b/rust-src/concordium_base/benches/elgamal_benchmarks.rs @@ -12,11 +12,12 @@ use concordium_base::{ Curve, }, elgamal::*, + id::constants::{ArCurve, BaseField}, }; use std::{str::FromStr, time::Duration}; -type G1 = ArkGroup; -type Fr = ArkField; +type G1 = ArCurve; +type Fr = BaseField; pub fn baby_step_giant_step_table_bench(c: &mut Criterion) { let mut csprng = thread_rng(); diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 9dd70531f..68319f788 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -62,8 +62,10 @@ impl Deserial for Fr { impl Serial for Fr { fn serial(&self, out: &mut B) { // Note that it is crucial to use `into_bigint()` here. - // The internal representation is accessible direclty, but it's NOT the same - // (it's a Montgomery representation optimized for modular arithmetic) + // The internal representation is accessible direclty, but it's NOT the same. + // The representation depends on the selected backend. + // By default, it's a Montgomery representation optimized for modular + // arithmetic. let frpr = self.into_bigint(); for a in frpr.0.iter().rev() { a.serial(out); diff --git a/rust-src/concordium_base/src/id/constants.rs b/rust-src/concordium_base/src/id/constants.rs index aec997f31..5ba94405e 100644 --- a/rust-src/concordium_base/src/id/constants.rs +++ b/rust-src/concordium_base/src/id/constants.rs @@ -9,8 +9,8 @@ use crate::{ curve_arithmetic::{arkworks_instances::ArkGroup, Curve, Pairing}, }; use anyhow::bail; -use ark_bls12_381::{g1, G1Projective}; -use ark_ec::{bls12::Bls12, short_weierstrass::Projective}; +use ark_bls12_381::{G1Projective, G2Projective}; +use ark_ec::bls12::Bls12; use serde::{ de::{self, Visitor}, Deserializer, Serializer, @@ -18,12 +18,14 @@ use serde::{ use std::{fmt, io::Cursor, str::FromStr}; use thiserror::Error; -/// Curve used by the anonymity revoker. -pub type ArCurve = ArkGroup>; +/// G1 group on the curve used by the anonymity revoker. +pub type ArCurve = ArkGroup; +/// G2 group on the curve used by the anonymity revoker. +pub type ArCurveG2 = ArkGroup; /// Pairing used by the identity provider. pub type IpPairing = Bls12; /// Field used by the identity provider and anonymity revoker. -/// This is the base field of both the ArCurve and the IpPairing. +/// This is the scalar field of both the ArCurve and the IpPairing. pub type BaseField = ::ScalarField; // pub type BaseField = ArkField; diff --git a/rust-src/concordium_base/src/sigma_protocols/com_ineq.rs b/rust-src/concordium_base/src/sigma_protocols/com_ineq.rs index ef9d689f5..3e32305b3 100644 --- a/rust-src/concordium_base/src/sigma_protocols/com_ineq.rs +++ b/rust-src/concordium_base/src/sigma_protocols/com_ineq.rs @@ -131,14 +131,13 @@ pub fn verify_com_ineq( #[cfg(test)] mod tests { - use crate::curve_arithmetic::arkworks_instances::{ArkField, ArkGroup}; + use crate::id::constants::{ArCurve, BaseField}; use super::*; - use ark_bls12_381::G1Projective; use std::str::FromStr; - type G1 = ArkGroup; - type Fr = ArkField; + type G1 = ArCurve; + type Fr = BaseField; #[test] fn test_com_ineq_correctness() { diff --git a/rust-src/concordium_base/src/sigma_protocols/com_lin.rs b/rust-src/concordium_base/src/sigma_protocols/com_lin.rs index 93b71612c..e0d9ad16a 100644 --- a/rust-src/concordium_base/src/sigma_protocols/com_lin.rs +++ b/rust-src/concordium_base/src/sigma_protocols/com_lin.rs @@ -217,16 +217,15 @@ impl SigmaProtocol for ComLin { #[allow(non_snake_case)] #[cfg(test)] mod tests { - use crate::curve_arithmetic::arkworks_instances::{ArkField, ArkGroup}; + use crate::id::constants::{ArCurve, BaseField}; use super::*; use crate::curve_arithmetic::PrimeField; - use ark_bls12_381::G1Projective; use rand::thread_rng; use std::str::FromStr; - type G1 = ArkGroup; - type Fr = ArkField; + type G1 = ArCurve; + type Fr = BaseField; #[test] pub fn test_com_lin_correctness() { diff --git a/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs b/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs index e58e247f3..0d175ea78 100644 --- a/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs +++ b/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs @@ -147,17 +147,17 @@ impl SigmaProtocol for DlogAndAggregateDlogsEqual { #[cfg(test)] mod test { use super::*; - use crate::curve_arithmetic::{ - arkworks_instances::{ArkField, ArkGroup}, - multiexp, + use crate::{ + curve_arithmetic::multiexp, + id::constants::{ArCurve, BaseField}, }; use rand::*; use ark_bls12_381::G1Projective; use std::str::FromStr; - type G1 = ArkGroup; - type Fr = ArkField; + type G1 = ArCurve; + type Fr = BaseField; pub fn generate_challenge_prefix(csprng: &mut R) -> Vec { // length of the challenge diff --git a/rust-src/concordium_base/src/sigma_protocols/dlogeq.rs b/rust-src/concordium_base/src/sigma_protocols/dlogeq.rs index 48f1ee76b..9c83b4f92 100644 --- a/rust-src/concordium_base/src/sigma_protocols/dlogeq.rs +++ b/rust-src/concordium_base/src/sigma_protocols/dlogeq.rs @@ -78,17 +78,16 @@ impl SigmaProtocol for DlogEqual { #[cfg(test)] mod test { use super::*; - use crate::curve_arithmetic::{ - arkworks_instances::{ArkField, ArkGroup}, - Value, + use crate::{ + curve_arithmetic::Value, + id::constants::{ArCurve, BaseField}, }; use rand::*; - use ark_bls12_381::G1Projective; use std::str::FromStr; - type G1 = ArkGroup; - type Fr = ArkField; + type G1 = ArCurve; + type Fr = BaseField; pub fn generate_challenge_prefix(csprng: &mut R) -> Vec { // length of the challenge From db989f65c6bcc38a887c82e4faac07fb7bf3bb4b Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 11 Jan 2024 15:58:34 +0100 Subject: [PATCH 27/53] Update changelog --- rust-src/concordium_base/CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust-src/concordium_base/CHANGELOG.md b/rust-src/concordium_base/CHANGELOG.md index 9cc24ece5..b069f7186 100644 --- a/rust-src/concordium_base/CHANGELOG.md +++ b/rust-src/concordium_base/CHANGELOG.md @@ -6,9 +6,9 @@ - Add traits `Field` and `PrimeField` with implementations for the underlying field of the `BLS12-381` curve. - Add integration with the `arkworks` library interfaces for fields and elliptic curves (wrapper types and blanket trait implementations). - Add the `BLS12-381`implementation from the `arkworks` ecosystem. -- Remove the `pairing` crate from dependencies along with the corresponding `BLS12-381` code (replaced with the `arkworks` implementation). -- Upgrade `ed25519-dalek` to `v2.0`. This leads to changes in FFI: - * the `pk_ptr` parameter is removed from `eddsa_sign` function; it is sufficient to supply a pointer to the secret key data. +- The public types `id::constants::ArCurve`, `id::constants::IpPairing` are defined in terms of the `arkworks` BLS12-381 implementation. +- Add a type alias `id::constants::ArCurveG2` for the `G2` group of `arkworks` BLS12-381. +- Upgrade `ed25519-dalek` to `v2.0`. - Bump the `rand` version to `v0.8` - Add implementations of `Field`, `PrimeField` and `Curve` for the Ristretto representation of `curve25519`. - Support `P7` protocol version. From d451d6649daa639a56873047d245360677145e72 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 11 Jan 2024 21:23:36 +0100 Subject: [PATCH 28/53] Rename ArCurveG1 into BlsG2 --- rust-bins/src/bin/keygen-genesis.rs | 4 ++-- rust-bins/src/bin/keygen.rs | 4 ++-- rust-src/concordium_base/CHANGELOG.md | 2 +- rust-src/concordium_base/src/id/constants.rs | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rust-bins/src/bin/keygen-genesis.rs b/rust-bins/src/bin/keygen-genesis.rs index f1bf345e7..9003fb94a 100644 --- a/rust-bins/src/bin/keygen-genesis.rs +++ b/rust-bins/src/bin/keygen-genesis.rs @@ -5,7 +5,7 @@ use concordium_base::{ curve_arithmetic::Curve, elgamal::PublicKey, id::{ - constants::{ArCurve, ArCurveG2, IpPairing}, + constants::{ArCurve, BlsG2, IpPairing}, types::*, }, ps_sig, @@ -17,7 +17,7 @@ use structopt::StructOpt; type Bls12 = IpPairing; type G1 = ArCurve; -type G2 = ArCurveG2; +type G2 = BlsG2; #[derive(StructOpt)] struct KeygenIp { diff --git a/rust-bins/src/bin/keygen.rs b/rust-bins/src/bin/keygen.rs index b049b11f2..8bb2e0280 100644 --- a/rust-bins/src/bin/keygen.rs +++ b/rust-bins/src/bin/keygen.rs @@ -5,7 +5,7 @@ use concordium_base::{ curve_arithmetic::Curve, elgamal::{PublicKey, SecretKey}, id::{ - constants::{ArCurve, ArCurveG2, BaseField, IpPairing}, + constants::{ArCurve, BaseField, BlsG2, IpPairing}, types::*, }, ps_sig, @@ -30,7 +30,7 @@ use structopt::StructOpt; type Bls12 = IpPairing; type G1 = ArCurve; -type G2 = ArCurveG2; +type G2 = BlsG2; type Fr = BaseField; const BIP39_ENGLISH: &str = include_str!("data/BIP39English.txt"); diff --git a/rust-src/concordium_base/CHANGELOG.md b/rust-src/concordium_base/CHANGELOG.md index b069f7186..1d73827ee 100644 --- a/rust-src/concordium_base/CHANGELOG.md +++ b/rust-src/concordium_base/CHANGELOG.md @@ -7,7 +7,7 @@ - Add integration with the `arkworks` library interfaces for fields and elliptic curves (wrapper types and blanket trait implementations). - Add the `BLS12-381`implementation from the `arkworks` ecosystem. - The public types `id::constants::ArCurve`, `id::constants::IpPairing` are defined in terms of the `arkworks` BLS12-381 implementation. -- Add a type alias `id::constants::ArCurveG2` for the `G2` group of `arkworks` BLS12-381. +- Add a type alias `id::constants::BlsG2` for the `G2` group of `arkworks` BLS12-381. - Upgrade `ed25519-dalek` to `v2.0`. - Bump the `rand` version to `v0.8` - Add implementations of `Field`, `PrimeField` and `Curve` for the Ristretto representation of `curve25519`. diff --git a/rust-src/concordium_base/src/id/constants.rs b/rust-src/concordium_base/src/id/constants.rs index 5ba94405e..1aa95dbe3 100644 --- a/rust-src/concordium_base/src/id/constants.rs +++ b/rust-src/concordium_base/src/id/constants.rs @@ -18,10 +18,10 @@ use serde::{ use std::{fmt, io::Cursor, str::FromStr}; use thiserror::Error; -/// G1 group on the curve used by the anonymity revoker. +/// Curve used by the anonymity revoker. pub type ArCurve = ArkGroup; -/// G2 group on the curve used by the anonymity revoker. -pub type ArCurveG2 = ArkGroup; +/// G2 group of the BLS12-381 curve +pub type BlsG2 = ArkGroup; /// Pairing used by the identity provider. pub type IpPairing = Bls12; /// Field used by the identity provider and anonymity revoker. From 351309adbbac109430791745936c57c71a79bd2f Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 11 Jan 2024 21:30:48 +0100 Subject: [PATCH 29/53] Remove sha2 v0.9 --- identity-provider-service/Cargo.lock | 1 - idiss/Cargo.lock | 1 - mobile_wallet/Cargo.lock | 1 - rust-bins/Cargo.lock | 1 - rust-bins/Cargo.toml | 2 +- rust-src/Cargo.lock | 1 - rust-src/concordium_base/Cargo.toml | 1 - 7 files changed, 1 insertion(+), 7 deletions(-) diff --git a/identity-provider-service/Cargo.lock b/identity-provider-service/Cargo.lock index e879d62f2..7a7e63211 100644 --- a/identity-provider-service/Cargo.lock +++ b/identity-provider-service/Cargo.lock @@ -514,7 +514,6 @@ dependencies = [ "serde_json", "serde_with", "sha2 0.10.8", - "sha2 0.9.9", "sha3", "subtle", "thiserror", diff --git a/idiss/Cargo.lock b/idiss/Cargo.lock index 40a23b057..be2e6a7e9 100644 --- a/idiss/Cargo.lock +++ b/idiss/Cargo.lock @@ -499,7 +499,6 @@ dependencies = [ "serde_json", "serde_with", "sha2 0.10.8", - "sha2 0.9.9", "sha3", "subtle", "thiserror", diff --git a/mobile_wallet/Cargo.lock b/mobile_wallet/Cargo.lock index 295877a5a..a169e4777 100644 --- a/mobile_wallet/Cargo.lock +++ b/mobile_wallet/Cargo.lock @@ -443,7 +443,6 @@ dependencies = [ "serde_json", "serde_with", "sha2 0.10.6", - "sha2 0.9.9", "sha3", "subtle", "thiserror", diff --git a/rust-bins/Cargo.lock b/rust-bins/Cargo.lock index f288c54c9..d5726c118 100644 --- a/rust-bins/Cargo.lock +++ b/rust-bins/Cargo.lock @@ -536,7 +536,6 @@ dependencies = [ "serde_json", "serde_with", "sha2 0.10.8", - "sha2 0.9.9", "sha3", "subtle", "thiserror", diff --git a/rust-bins/Cargo.toml b/rust-bins/Cargo.toml index 598c43ef8..bc3499cd5 100644 --- a/rust-bins/Cargo.toml +++ b/rust-bins/Cargo.toml @@ -16,7 +16,7 @@ dialoguer = "0.10" rand = "=0.8" serde = "1.0" serde_json = "1.0" -ed25519-dalek = {version = "2.0"} +ed25519-dalek = "2.0" curve25519-dalek = "4.0" structopt = "0.3" hex = "0.4" diff --git a/rust-src/Cargo.lock b/rust-src/Cargo.lock index 435341f22..545cdee5a 100644 --- a/rust-src/Cargo.lock +++ b/rust-src/Cargo.lock @@ -537,7 +537,6 @@ dependencies = [ "serde_json", "serde_with", "sha2 0.10.7", - "sha2 0.9.9", "sha3", "subtle", "thiserror", diff --git a/rust-src/concordium_base/Cargo.toml b/rust-src/concordium_base/Cargo.toml index 749d320c8..3db9fceca 100644 --- a/rust-src/concordium_base/Cargo.toml +++ b/rust-src/concordium_base/Cargo.toml @@ -19,7 +19,6 @@ ark-serialize = { version = "0.4"} ark-std = { version = "0.4"} ark-bls12-381 = { version = "0.4"} sha2 = "0.10" -sha2-old = { version = "0.9", package = "sha2" } sha3 = "0.10" anyhow = "1.0" serde = {version = "1.0", features = ["derive"]} From 6031cc55fd7c0fdd2e0e82cdabb0ec24d25edd1c Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 11 Jan 2024 21:52:31 +0100 Subject: [PATCH 30/53] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Aleš Bizjak --- rust-src/concordium_base/Cargo.toml | 2 +- .../src/curve_arithmetic/arkworks_instances.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/rust-src/concordium_base/Cargo.toml b/rust-src/concordium_base/Cargo.toml index 749d320c8..151b0c48b 100644 --- a/rust-src/concordium_base/Cargo.toml +++ b/rust-src/concordium_base/Cargo.toml @@ -37,7 +37,7 @@ thiserror = "1.0" rand = "0.8" num = "0.4" group = "0.2" -curve25519-dalek = { version = "4.1.1", features = ["rand_core", "group"]} +curve25519-dalek = { version = "4.1", features = ["rand_core", "group"]} zeroize = "1.1" # See https://github.com/serde-rs/json/issues/505 for the need to be careful. rust_decimal = { version = "1.25", features = ["serde-float", "serde-arbitrary-precision"]} diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 8672153fa..7098be8a9 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -2,9 +2,7 @@ //! `arkworks` field/curve traits. use core::fmt; use std::str::FromStr; - use crate::common::{Deserial, Serial, Serialize}; - use super::{Curve, CurveDecodingError, Field, GenericMultiExp, PrimeField}; use anyhow::anyhow; use ark_ec::hashing::HashToCurve; @@ -104,7 +102,7 @@ impl Serial for ArkGroup { self.0 .into_affine() .serialize_compressed(out) - .expect("Serialzation expected to succeed"); + .expect("Serialization expected to succeed"); } } From 68f32d661f0e038c074bfb29088ef20bda92bbc0 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 11 Jan 2024 21:57:45 +0100 Subject: [PATCH 31/53] Remove ark dependency from keygen-bls; use reexported types from concordium_base::id::constants --- mobile_wallet/Cargo.lock | 1 - rust-bins/Cargo.lock | 1 - rust-src/Cargo.lock | 1 - rust-src/keygen_bls/Cargo.toml | 1 - rust-src/keygen_bls/src/lib.rs | 27 ++++++++++++--------------- 5 files changed, 12 insertions(+), 19 deletions(-) diff --git a/mobile_wallet/Cargo.lock b/mobile_wallet/Cargo.lock index a169e4777..6ddc5f595 100644 --- a/mobile_wallet/Cargo.lock +++ b/mobile_wallet/Cargo.lock @@ -1016,7 +1016,6 @@ dependencies = [ name = "keygen_bls" version = "2.0.0" dependencies = [ - "ark-bls12-381", "concordium_base", "ff 0.5.2", "hex", diff --git a/rust-bins/Cargo.lock b/rust-bins/Cargo.lock index d5726c118..8e9da4913 100644 --- a/rust-bins/Cargo.lock +++ b/rust-bins/Cargo.lock @@ -1376,7 +1376,6 @@ dependencies = [ name = "keygen_bls" version = "2.0.0" dependencies = [ - "ark-bls12-381", "concordium_base", "ff 0.5.2", "hex", diff --git a/rust-src/Cargo.lock b/rust-src/Cargo.lock index 545cdee5a..c6291c532 100644 --- a/rust-src/Cargo.lock +++ b/rust-src/Cargo.lock @@ -1126,7 +1126,6 @@ dependencies = [ name = "keygen_bls" version = "2.0.0" dependencies = [ - "ark-bls12-381", "concordium_base", "ff 0.5.2", "hex", diff --git a/rust-src/keygen_bls/Cargo.toml b/rust-src/keygen_bls/Cargo.toml index 7a8615772..04621bae8 100644 --- a/rust-src/keygen_bls/Cargo.toml +++ b/rust-src/keygen_bls/Cargo.toml @@ -10,7 +10,6 @@ sha2 = "0.10" hkdf = "0.12.0" ff = "0.5" hex = "0.4" -ark-bls12-381 = { version = "0.4" } [dependencies.concordium_base] path = "../concordium_base" diff --git a/rust-src/keygen_bls/src/lib.rs b/rust-src/keygen_bls/src/lib.rs index 8f793225b..f8bd636dc 100644 --- a/rust-src/keygen_bls/src/lib.rs +++ b/rust-src/keygen_bls/src/lib.rs @@ -1,21 +1,21 @@ //! Generate a private key in a deterministic way from a secret seed and key //! description. -use ark_bls12_381::{Fr, G1Projective}; -use concordium_base::curve_arithmetic::{ - arkworks_instances::{ArkField, ArkGroup}, - Curve, Field, PrimeField, +use concordium_base::{ + curve_arithmetic::{Curve, Field, PrimeField}, + id::constants::{ArCurve, BaseField}, }; use hkdf::Hkdf; use sha2::{Digest, Sha256}; -type G1 = ArkGroup; +type G1 = ArCurve; +type Fr = BaseField; /// This function is an implementation of the procedure described in /// It computes a random scalar in Fr given a seed (the argument `ikm`). /// /// This is a building block for deterministic key generation for identity /// provider, anonymity revoker keys and PRF keys. -pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result, hkdf::InvalidLength> { +pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result { let mut ikm = ikm.to_vec(); ikm.push(0); let l = 48; // = 48 for G1; r is @@ -24,11 +24,11 @@ pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result, hkdf::Inv l_bytes.push(0); l_bytes.push(l); let salt = b"BLS-SIG-KEYGEN-SALT-"; - let mut sk = >::zero(); + let mut sk = ::zero(); // shift with // 452312848583266388373324160190187140051835877600158453279131187530910662656 = // 2^248 = 2^(31*8) - let shift = >::from_repr(&[0, 0, 0, 72057594037927936]).unwrap(); + let shift = Fr::from_repr(&[0, 0, 0, 72057594037927936]).unwrap(); println!("Shift {:}", shift); let mut salt = Sha256::digest(&salt[..]); while sk.is_zero() { @@ -66,10 +66,7 @@ pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result, hkdf::Inv /// an integer modulo r. It therefore does not follow the standard (cf. ), /// but is still secure. /// This function is needed for backwards compatibility. -pub fn keygen_bls_deprecated( - ikm: &[u8], - key_info: &[u8], -) -> Result, hkdf::InvalidLength> { +pub fn keygen_bls_deprecated(ikm: &[u8], key_info: &[u8]) -> Result { let mut ikm = ikm.to_vec(); ikm.push(0); let l = 48; // = 48 for G1; r is @@ -78,11 +75,11 @@ pub fn keygen_bls_deprecated( l_bytes.push(l); l_bytes.push(0); let salt = b"BLS-SIG-KEYGEN-SALT-"; - let mut sk = >::zero(); + let mut sk = ::zero(); // shift with // 452312848583266388373324160190187140051835877600158453279131187530910662656 = // 2^248 - let shift = >::from_repr(&[0, 0, 0, 72057594037927936]).unwrap(); + let shift = ::from_repr(&[0, 0, 0, 72057594037927936]).unwrap(); let mut salt = Sha256::digest(&salt[..]); while sk.is_zero() { let (_, h) = Hkdf::::extract(Some(&salt), &ikm); @@ -192,7 +189,7 @@ mod tests { for i in 0..10 { if let Ok(seed) = hex::decode(inputs[i]) { if let Ok(sk) = keygen_bls(&seed, b"") { - let res: ArkField = sk.into(); + let res: Fr = sk.into(); assert_eq!(res.into_repr(), expected_outputs[i]) } else { panic!("Could not generate key from seed.") From e1d61c48477fc62a0a21751c2b4975672f7685f0 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 11 Jan 2024 22:00:57 +0100 Subject: [PATCH 32/53] Remove debug prints --- rust-src/key_derivation/src/lib.rs | 8 -------- rust-src/keygen_bls/src/lib.rs | 1 - 2 files changed, 9 deletions(-) diff --git a/rust-src/key_derivation/src/lib.rs b/rust-src/key_derivation/src/lib.rs index 352dd867b..4541b3c71 100644 --- a/rust-src/key_derivation/src/lib.rs +++ b/rust-src/key_derivation/src/lib.rs @@ -258,10 +258,6 @@ impl ConcordiumHdWallet { ])?; let attribute_commitment_randomness_seed = derive_from_parsed_path(&path, &self.seed)?.private_key; - println!( - "attribute_commitment_randomness_seed: {:?}", - attribute_commitment_randomness_seed - ); Ok(CommitmentRandomness::new(bls_key_bytes_from_seed( attribute_commitment_randomness_seed, ))) @@ -574,10 +570,6 @@ mod tests { let attribute_commitment_randomness = create_wallet(Net::Testnet, TEST_SEED_1) .get_attribute_commitment_randomness(5, 0, 4, AttributeTag(0)) .unwrap(); - println!( - "attribute_commitment_randomness: {:?}", - attribute_commitment_randomness - ); assert_eq!( base16_encode_string(&attribute_commitment_randomness), "409fa90314ec8fb4a2ae812fd77fe58bfac81765cad3990478ff7a73ba6d88ae" diff --git a/rust-src/keygen_bls/src/lib.rs b/rust-src/keygen_bls/src/lib.rs index f8bd636dc..292d198ca 100644 --- a/rust-src/keygen_bls/src/lib.rs +++ b/rust-src/keygen_bls/src/lib.rs @@ -29,7 +29,6 @@ pub fn keygen_bls(ikm: &[u8], key_info: &[u8]) -> Result::extract(Some(&salt), &ikm); From b9d648efb56486750c04c6a622abe7806f575a0c Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 11 Jan 2024 22:06:14 +0100 Subject: [PATCH 33/53] Formatting; derive FromStr for ArkField --- .../src/curve_arithmetic/arkworks_instances.rs | 15 +++++---------- .../src/sigma_protocols/dlogaggequal.rs | 2 -- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 7098be8a9..4b53cb32a 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -1,15 +1,16 @@ //! Wrapper types and blanket implementations serving as adapters from //! `arkworks` field/curve traits. -use core::fmt; -use std::str::FromStr; -use crate::common::{Deserial, Serial, Serialize}; use super::{Curve, CurveDecodingError, Field, GenericMultiExp, PrimeField}; +use crate::common::{Deserial, Serial, Serialize}; use anyhow::anyhow; use ark_ec::hashing::HashToCurve; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use core::fmt; /// A wrapper type for `arkworks` field types. -#[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, fmt::Debug, derive_more::From)] +#[derive( + PartialOrd, Ord, PartialEq, Eq, Copy, Clone, fmt::Debug, derive_more::From, derive_more::FromStr, +)] pub struct ArkField(pub(crate) F); /// Serialization is implemented by delegating the functionality to the wrapped @@ -197,9 +198,3 @@ where ArkGroup(res.into()) } } - -impl FromStr for ArkField { - type Err = F::Err; - - fn from_str(s: &str) -> Result { F::from_str(s).map(|x| x.into()) } -} diff --git a/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs b/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs index 0d175ea78..f984ccb4a 100644 --- a/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs +++ b/rust-src/concordium_base/src/sigma_protocols/dlogaggequal.rs @@ -152,8 +152,6 @@ mod test { id::constants::{ArCurve, BaseField}, }; use rand::*; - - use ark_bls12_381::G1Projective; use std::str::FromStr; type G1 = ArCurve; From 7fdf2e070ab699bff7ecabadce34eae05ae13ad6 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 11 Jan 2024 23:09:07 +0100 Subject: [PATCH 34/53] Make scalar_from_bytes work properly for any curve --- .../src/curve_arithmetic/arkworks_instances.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 4b53cb32a..ff9aac654 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -175,8 +175,7 @@ where fn scalar_from_u64(n: u64) -> Self::Scalar { ArkField(G::ScalarField::from(n)) } fn scalar_from_bytes>(bs: A) -> Self::Scalar { - // Traverse at most 4 8-byte chunks, for a total of 256 bits. - // The top-most two bits in the last chunk are set to 0. + // Traverse at most `ceil(CAPACITY / 8)` 8-byte chunks. let s = num::integer::div_ceil(Self::Scalar::CAPACITY, 8); let mut fr = Vec::with_capacity(s as usize); for chunk in bs.as_ref().chunks(8).take(s as usize) { @@ -184,9 +183,15 @@ where v[..chunk.len()].copy_from_slice(chunk); fr.push(u64::from_le_bytes(v)); } - // unset two topmost bits in the last read u64. - *fr.last_mut().expect("Non empty vector expected") &= !(1u64 << 63 | 1u64 << 62); - // fr[3] &= !(1u64 << 63 | 1u64 << 62); + let total_size_in_bits = bs.as_ref().len() * 8; + let num_bits_to_remove = total_size_in_bits as u32 - Self::Scalar::CAPACITY; + // create a mask for the last chunk with the topmost `num_bits_to_remove` zeros + // followed by `CAPACITY` of ones; it's implemented using (logical) right shift + // that adds zeros from the left. E.g. if `num_bits_to_remove = 2`, the + // mask will be `00111..11` + let mask = u64::MAX >> num_bits_to_remove; + // unset `num_bits_to_remove` topmost bits in the last u64. + *fr.last_mut().expect("Non empty vector expected") &= mask; ::from_repr(&fr) .expect("The scalar with top two bits erased should be valid.") } From bb8dd043582ce75ca551e237a87ce695aeef6b27 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Fri, 12 Jan 2024 08:45:36 +0100 Subject: [PATCH 35/53] Fixed comments and cleanup related to affine representation --- .../concordium_base/src/curve_arithmetic/secret_value.rs | 8 ++------ rust-src/concordium_base/src/pedersen_commitment/key.rs | 6 ------ .../concordium_base/src/pedersen_commitment/randomness.rs | 3 --- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/secret_value.rs b/rust-src/concordium_base/src/curve_arithmetic/secret_value.rs index 3cf6612b6..ad3d40be5 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/secret_value.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/secret_value.rs @@ -120,17 +120,13 @@ mod tests { }; } - // TODO: the code used to be diefined using the affine representation, but - // ArkWorks' BLS does not implement `CurveGroup` for the affine representation. - // Is it important that it's the affine representation? For now, the BLS - // projective representation will be used here. macro_test_value_to_byte_conversion!( - value_to_byte_conversion_bls12_381_g1_affine, + value_to_byte_conversion_bls12_381_g1_projective, ArkGroup ); macro_test_value_to_byte_conversion!( - value_to_byte_conversion_bls12_381_g2_affine, + value_to_byte_conversion_bls12_381_g2_projective, ArkGroup ); } diff --git a/rust-src/concordium_base/src/pedersen_commitment/key.rs b/rust-src/concordium_base/src/pedersen_commitment/key.rs index cd2222123..27d756ba2 100644 --- a/rust-src/concordium_base/src/pedersen_commitment/key.rs +++ b/rust-src/concordium_base/src/pedersen_commitment/key.rs @@ -170,8 +170,6 @@ mod tests { }; } - // NOTE: ArkWorks doesn't provide `CurveGroup` instances for the affine - // representation macro_test_key_byte_conversion!(key_byte_conversion_bls12_381_g1_projective, G1); macro_test_key_byte_conversion!(key_byte_conversion_bls12_381_g2_projective, G2); @@ -223,15 +221,11 @@ mod tests { }; } - // macro_test_commit_open!(commit_open_bls12_381_g1_affine, G1Affine); macro_test_commit_open!(commit_open_bls12_381_g1_projectitve, G1); - // macro_test_commit_open!(commit_open_bls12_381_g2_affine, G2Affine); macro_test_commit_open!(commit_open_bls12_381_g2_projective, G2); - // macro_test_commit_open_vec!(vec_commit_open_bls12_381_g1_affine, G1Affine); macro_test_commit_open_vec!(vec_commit_open_bls12_381_g1_projective, G1); - // macro_test_commit_open_vec!(vec_commit_open_bls12_381_g2_affine, G2Affine); macro_test_commit_open_vec!(vec_commit_open_bls12_381_g2_projective, G2); } diff --git a/rust-src/concordium_base/src/pedersen_commitment/randomness.rs b/rust-src/concordium_base/src/pedersen_commitment/randomness.rs index 8d7afa55b..e09f5a531 100644 --- a/rust-src/concordium_base/src/pedersen_commitment/randomness.rs +++ b/rust-src/concordium_base/src/pedersen_commitment/randomness.rs @@ -101,9 +101,6 @@ mod tests { }; } - // NOTE: ArkWorks doesn't provide `CurveGroup` instances for the affine - // representation - macro_test_randomness_to_byte_conversion!( randomness_to_byte_conversion_bls12_381_g1_projective, G1 From 0ac15e072fa6810b60da229ad1872c969d4f5b96 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Fri, 12 Jan 2024 08:58:33 +0100 Subject: [PATCH 36/53] Update field adapter documentation --- .../concordium_base/src/curve_arithmetic/field_adapters.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/field_adapters.rs b/rust-src/concordium_base/src/curve_arithmetic/field_adapters.rs index bafc43a8b..56d197fec 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/field_adapters.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/field_adapters.rs @@ -1,5 +1,8 @@ //! Wrapper types and blanket implementations serving as adapters from -//! the `ff` crate `Field`. +//! the `ff` crate `Field`. The Ristretto representation from the +//! `curve25519-dalek` uses the `ff` traits for the fields involved. The crate +//! is relatively widely used, so it could be useful for integrating with other +//! elliptic curve implementations. use ff; use rand::RngCore; From cc8e78e1852af93e012cbf3de2122e72201d55ec Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Fri, 12 Jan 2024 11:56:57 +0100 Subject: [PATCH 37/53] Fixes after review: update ArkCurveConfig; improve error reporting in test --- .../src/curve_arithmetic/arkworks_instances.rs | 6 ++++++ .../src/curve_arithmetic/bls12_381_arkworks.rs | 2 +- .../src/curve_arithmetic/ed25519_instance.rs | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index ff9aac654..24465d75e 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -121,9 +121,15 @@ impl Deserial for ArkGroup { /// These parameters cannot be taken from the `arkworks` traits. Each `arkworks` /// curve should come with an implementation of this configuration trait. pub(crate) trait ArkCurveConfig { + /// Size in bytes of elements of the scalar field. const SCALAR_LENGTH: usize; + /// Size in bytes of group elements when serialized. const GROUP_ELEMENT_LENGTH: usize; + /// Domain separation string for hashing arbitrary data to a group element + /// on an elliptic curve. const DOMAIN_STRING: &'static str; + /// A hasher that implements hashing arbitrary data to a group element on an + /// elliptic curve. type Hasher: ark_ec::hashing::HashToCurve; } diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 68319f788..8fb953fb9 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -62,7 +62,7 @@ impl Deserial for Fr { impl Serial for Fr { fn serial(&self, out: &mut B) { // Note that it is crucial to use `into_bigint()` here. - // The internal representation is accessible direclty, but it's NOT the same. + // The internal representation is accessible directly, but it's NOT the same. // The representation depends on the selected backend. // By default, it's a Montgomery representation optimized for modular // arithmetic. diff --git a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs index f15288e3e..e9e7ba91d 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs @@ -271,12 +271,12 @@ pub(crate) mod tests { /// byte array to an array of limbs with least significant digits first. #[test] fn test_into() { - let s: RistrettoScalar = Scalar::from_canonical_bytes([ + let res: Option = Scalar::from_canonical_bytes([ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, ]) - .unwrap() .into(); + let s: RistrettoScalar = res.expect("Expected a valid scalar").into(); assert_eq!(s.into_repr(), [1u64, 0u64, u64::MAX - 1, 0u64]); } From b3f02d7e704d4e622e593db636f6b55dffcef8f6 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Fri, 12 Jan 2024 13:18:35 +0100 Subject: [PATCH 38/53] Remove Curve::bytes_to_curve_unchecked() corresponding implementations and tests; rename to Cipher::from_bytes(); the method uses deserial() instead of Curve::bytes_to_curve_unchecked() --- rust-src/concordium_base/CHANGELOG.md | 2 ++ .../curve_arithmetic/arkworks_instances.rs | 9 -------- .../curve_arithmetic/bls12_381_arkworks.rs | 21 ----------------- .../src/curve_arithmetic/ed25519_instance.rs | 23 ------------------- .../src/curve_arithmetic/mod.rs | 5 ---- .../concordium_base/src/elgamal/cipher.rs | 6 ++--- 6 files changed, 5 insertions(+), 61 deletions(-) diff --git a/rust-src/concordium_base/CHANGELOG.md b/rust-src/concordium_base/CHANGELOG.md index 1d73827ee..9571b31bd 100644 --- a/rust-src/concordium_base/CHANGELOG.md +++ b/rust-src/concordium_base/CHANGELOG.md @@ -11,6 +11,8 @@ - Upgrade `ed25519-dalek` to `v2.0`. - Bump the `rand` version to `v0.8` - Add implementations of `Field`, `PrimeField` and `Curve` for the Ristretto representation of `curve25519`. +- Remove `Curve::bytes_to_curve_unchecked()`. +- Rename `Cipher::from_bytes_unchecked()` to `Cipher::from_bytes()`; the method uses `deserial()` instead of `Curve::bytes_to_curve_unchecked()`. - Support `P7` protocol version. - The `Debug` implementation for `ContractEvent` displays the value in `hex`. The alternate formatter (using `#`) displays it as a list of bytes. diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 24465d75e..62e0d5388 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -2,7 +2,6 @@ //! `arkworks` field/curve traits. use super::{Curve, CurveDecodingError, Field, GenericMultiExp, PrimeField}; use crate::common::{Deserial, Serial, Serialize}; -use anyhow::anyhow; use ark_ec::hashing::HashToCurve; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use core::fmt; @@ -164,14 +163,6 @@ where fn mul_by_scalar(&self, scalar: &Self::Scalar) -> Self { ArkGroup(self.0 * scalar.0) } - fn bytes_to_curve_unchecked(b: &mut R) -> anyhow::Result { - // TODO: this is not the most efficient implementation, since there might be - // some additional checks during deserialization. However, it seems - // there are no unchecked methods available through traits. - let res = G::Affine::deserialize_compressed(b).map_err(|e| anyhow!(e))?; - Ok(ArkGroup(res.into())) - } - fn generate(rng: &mut R) -> Self { ArkGroup(G::rand(rng)) } fn generate_scalar(rng: &mut R) -> Self::Scalar { diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 8fb953fb9..622f14874 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -262,24 +262,6 @@ mod tests { }; } - /// A macro for testing that serializing a point and converting it back - /// using `bytes_to_curve_unchecked` gives the same point. - macro_rules! macro_test_group_byte_conversion_unchecked { - ($function_name:ident, $p:path) => { - #[test] - pub fn $function_name() { - let mut csprng = thread_rng(); - for _ in 0..1000 { - let curve = <$p>::generate(&mut csprng); - let bytes = to_bytes(&curve); - let curve_res = <$p>::bytes_to_curve_unchecked(&mut Cursor::new(&bytes)); - assert!(curve_res.is_ok()); - assert_eq!(curve, curve_res.unwrap()); - } - } - }; - } - type G1 = ArkGroup; type G2 = ArkGroup; @@ -289,7 +271,4 @@ mod tests { macro_test_group_byte_conversion!(curve_bytes_conv_g1, G1); macro_test_group_byte_conversion!(curve_bytes_conv_g2, G2); - - macro_test_group_byte_conversion_unchecked!(u_curve_bytes_conv_g1, G1); - macro_test_group_byte_conversion_unchecked!(u_curve_bytes_conv_g2, G2); } diff --git a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs index e9e7ba91d..7bc2bac20 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs @@ -114,16 +114,6 @@ impl Curve for RistrettoPoint { fn mul_by_scalar(&self, scalar: &Self::Scalar) -> Self { self * scalar.0 } - fn bytes_to_curve_unchecked( - source: &mut R, - ) -> anyhow::Result { - let mut buf: [u8; 32] = [0; 32]; - source.read_exact(&mut buf)?; - let res = CompressedRistretto::from_slice(&buf)?; - let point = res.decompress().ok_or(anyhow::anyhow!("Failed!"))?; - Ok(point) - } - fn generate(rng: &mut R) -> Self { let mut uniform_bytes = [0u8; 64]; rng.fill_bytes(&mut uniform_bytes); @@ -254,19 +244,6 @@ pub(crate) mod tests { } } - /// Turn curve points into representations and back again, and compare. - #[test] - fn test_point_byte_conversion_unchecked() { - let mut csprng = rand::thread_rng(); - for _ in 0..1000 { - let point = RistrettoPoint::generate(&mut csprng); - let bytes = to_bytes(&point); - let point_res = RistrettoPoint::bytes_to_curve_unchecked(&mut Cursor::new(&bytes)); - assert!(point_res.is_ok()); - assert_eq!(point, point_res.unwrap()); - } - } - /// Test that `into_repr()` correclty converts a scalar constructed from a /// byte array to an array of limbs with least significant digits first. #[test] diff --git a/rust-src/concordium_base/src/curve_arithmetic/mod.rs b/rust-src/concordium_base/src/curve_arithmetic/mod.rs index 6d3ba9878..ee6f4d7d3 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/mod.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/mod.rs @@ -9,7 +9,6 @@ pub mod secret_value; pub use secret_value::{Secret, Value}; use crate::common::{Serial, Serialize}; -use byteorder::ReadBytesExt; use rand::*; use std::{borrow::Borrow, fmt, fmt::Debug}; use thiserror::Error; @@ -136,10 +135,6 @@ pub trait Curve: /// Exponentiation by a scalar, i.e., compute n * x for a group element x /// and integer n. fn mul_by_scalar(&self, scalar: &Self::Scalar) -> Self; - /// Deserialize a value from a byte source, but do not check that it is in - /// the group itself. This can be cheaper if the source of the value is - /// trusted, but it must not be used on untrusted sources. - fn bytes_to_curve_unchecked(b: &mut R) -> anyhow::Result; /// Generate a random group element, uniformly distributed. fn generate(rng: &mut R) -> Self; /// Generate a random scalar value, uniformly distributed. diff --git a/rust-src/concordium_base/src/elgamal/cipher.rs b/rust-src/concordium_base/src/elgamal/cipher.rs index c49c6fd7d..388fb5104 100644 --- a/rust-src/concordium_base/src/elgamal/cipher.rs +++ b/rust-src/concordium_base/src/elgamal/cipher.rs @@ -56,9 +56,9 @@ impl Cipher { /// A `Result` whose okay value is a cipher key or whose error value /// is an `ElgamalError` wrapping the internal error that occurred. #[inline] - pub fn from_bytes_unchecked(bytes: &mut R) -> anyhow::Result> { - let g = C::bytes_to_curve_unchecked(bytes)?; - let h = C::bytes_to_curve_unchecked(bytes)?; + pub fn from_bytes(bytes: &mut R) -> anyhow::Result> { + let g = C::deserial(bytes)?; + let h = C::deserial(bytes)?; Ok(Cipher(g, h)) } From 778d9f33766185f50724afaaa66128fc4713f7c7 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 15 Jan 2024 09:19:08 +0100 Subject: [PATCH 39/53] Add hash-to-curve tests from the previous implementation --- .../curve_arithmetic/bls12_381_arkworks.rs | 305 +++++++++++++++++- 1 file changed, 304 insertions(+), 1 deletion(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 622f14874..4a1bd62d7 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -154,14 +154,20 @@ impl fmt::Display for ArkField { #[cfg(test)] mod tests { + use std::str::FromStr; + use super::*; use crate::{ common::*, curve_arithmetic::{Curve, Field, PrimeField}, }; + use ark_ec::hashing::HashToCurve; + use ark_ff::field_hashers::HashToField; use num_bigint::BigUint; + use num_traits::One; use rand::thread_rng; - use std::io::Cursor; + + type Fq = ArkField; const SCALAR_BYTES_LE: [u8; 32] = [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 0, @@ -265,10 +271,307 @@ mod tests { type G1 = ArkGroup; type G2 = ArkGroup; + fn from_coordinates_unchecked(x: Fq, y: Fq, z: Fq) -> G1 { + G1Projective::new_unchecked(x.0, y.0, z.0).into() + } + + fn from_coordinates_unchecked_g2(x: Fq2, y: Fq2, z: Fq2) -> G2 { + G2Projective::new_unchecked(x, y, z).into() + } + macro_test_scalar_byte_conversion!(sc_bytes_conv_g1, G1); macro_test_scalar_byte_conversion!(sc_bytes_conv_g2, G2); macro_test_scalar_byte_conversion!(sc_bytes_conv_bls12, Bls12); macro_test_group_byte_conversion!(curve_bytes_conv_g1, G1); macro_test_group_byte_conversion!(curve_bytes_conv_g2, G2); + + fn hash_to_curve(msg: &[u8], dst: &[u8]) -> G1 { + let hasher = >::Hasher::new(dst) + .expect("Expected valid domain separation string"); + let res = >::Hasher::hash(&hasher, msg) + .expect("Expected successful hashing to curve"); + ArkGroup(res.into()) + } + + fn hash_to_curve_g2(msg: &[u8], dst: &[u8]) -> G2 { + let hasher = >::Hasher::new(dst) + .expect("Expected valid domain separation string"); + let res = >::Hasher::hash(&hasher, msg) + .expect("Expected successful hashing to curve"); + ArkGroup(res.into()) + } + + fn hash_to_field_fq2(msg: &[u8], dst: &[u8]) -> (Fq2, Fq2) { + let hasher = as HashToField>::new(dst); + let fs: Vec = hasher.hash_to_field(msg, 2); + (fs[0], fs[1]) + } + + // This tests the function hash_to_curve function according to + // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-J.9.1 with + // suite = BLS12381G1_XMD:SHA-256_SSWU_RO_ + // dst = QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_ + #[test] + fn test_hash_to_curve() { + let msg = "".as_bytes(); + let dst = b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_"; + let p = hash_to_curve(msg, &dst[..]); + assert_eq!(to_bytes(&p), vec![ + 133, 41, 38, 173, 210, 32, 123, 118, 202, 79, 165, 122, 135, 52, 65, 108, 141, 201, 94, + 36, 80, 23, 114, 200, 20, 39, 135, 0, 238, 214, 209, 228, 232, 207, 98, 217, 192, 157, + 176, 250, 195, 73, 97, 43, 117, 158, 121, 161 + ]); + // The point should have (in hex) + // P.x = 052926add2207b76ca4fa57a8734416c8dc95e24501772c8142787 + // 00eed6d1e4e8cf62d9c09db0fac349612b759e79a1 + // P.y = 08ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c6 + // 7e2e81a4cc68ee29813bb7994998f3eae0c9c6a265 + assert_eq!(p, from_coordinates_unchecked( + Fq::from_str("794311575721400831362957049303781044852006323422624111893352859557450008308620925451441746926395141598720928151969").unwrap(), + Fq::from_str("1343412193624222137939591894701031123123641958980729764240763391191550653712890272928110356903136085217047453540965").unwrap(), + Fq::one())); + let msg = "abc".as_bytes(); + let p = hash_to_curve(msg, &dst[..]); + assert_eq!(to_bytes(&p), vec![ + 131, 86, 123, 197, 239, 156, 105, 12, 42, 178, 236, 223, 106, 150, 239, 28, 19, 156, + 192, 178, 242, 132, 220, 160, 169, 167, 148, 51, 136, 164, 154, 58, 238, 102, 75, 165, + 55, 154, 118, 85, 211, 198, 137, 0, 190, 47, 105, 3 + ]); + // The point should have (in hex) + // P.x = 03567bc5ef9c690c2ab2ecdf6a96ef1c139cc0b2f284dca0a9a794 + // 3388a49a3aee664ba5379a7655d3c68900be2f6903 + // P.y = 0b9c15f3fe6e5cf4211f346271d7b01c8f3b28be689c8429c85b67 + // af215533311f0b8dfaaa154fa6b88176c229f2885d + assert_eq!(p, from_coordinates_unchecked( + Fq::from_str("513738460217615943921285247703448567647875874745567372796164155472383127756567780059136521508428662765965997467907").unwrap(), + Fq::from_str("1786897908129645780825838873875416513994655004408749907941296449131605892957529391590865627492442562626458913769565").unwrap(), + Fq::one())); + let msg = "abcdef0123456789".as_bytes(); + let p = hash_to_curve(msg, &dst[..]); + assert_eq!(to_bytes(&p), vec![ + 145, 224, 176, 121, 222, 162, 154, 104, 240, 56, 62, 233, 79, 237, 27, 148, 9, 149, 39, + 36, 7, 227, 187, 145, 107, 191, 38, 140, 38, 61, 221, 87, 166, 162, 114, 0, 167, 132, + 203, 194, 72, 232, 79, 53, 124, 232, 45, 152 + ]); + // The point should have (in hex) + // P.x = 11e0b079dea29a68f0383ee94fed1b940995272407e3bb916bbf26 + // 8c263ddd57a6a27200a784cbc248e84f357ce82d98 + // P.y = 03a87ae2caf14e8ee52e51fa2ed8eefe80f02457004ba4d486d6aa + // 1f517c0889501dc7413753f9599b099ebcbbd2d709 + assert_eq!(p, from_coordinates_unchecked( + Fq::from_str("2751628761372137084683207295437105268166375184027748372156952770986741873369176463286511518644061904904607431667096").unwrap(), + Fq::from_str("563036982304416203921640398061260377444881693369806087719971277317609936727208012968659302318886963927918562170633").unwrap(), + Fq::one())); + let msg = "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq".as_bytes(); + let p = hash_to_curve(msg, &dst[..]); + assert_eq!(to_bytes(&p), vec![ + 181, 246, 142, 170, 105, 59, 149, 204, 184, 82, 21, 220, 101, 250, 129, 3, 141, 105, + 98, 159, 112, 174, 238, 13, 15, 103, 124, 242, 34, 133, 231, 191, 88, 215, 203, 134, + 238, 254, 143, 46, 155, 195, 248, 203, 132, 250, 196, 136 + ]); + // The point should have (in hex) + // P.x = 15f68eaa693b95ccb85215dc65fa81038d69629f70aeee0d0f677c + // f22285e7bf58d7cb86eefe8f2e9bc3f8cb84fac488 + // P.y = 1807a1d50c29f430b8cafc4f8638dfeeadf51211e1602a5f184443 + // 076715f91bb90a48ba1e370edce6ae1062f5e6dd38 + assert_eq!(p, from_coordinates_unchecked( + Fq::from_str("3380432694887674439773082418192083720584748080704959172978586229921475315220434165460350679208315690319508336723080").unwrap(), + Fq::from_str("3698526739072864408749571082270628561764415577445404115596990919801523793138348254443092179877354467167123794222392").unwrap(), + Fq::one())); + let msg = "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".as_bytes(); + let p = hash_to_curve(msg, &dst[..]); + assert_eq!(to_bytes(&p), vec![ + 136, 42, 171, 174, 139, 125, 237, 176, 231, 138, 235, 97, 154, 211, 191, 217, 39, 122, + 47, 119, 186, 127, 173, 32, 239, 106, 171, 220, 108, 49, 209, 155, 165, 166, 209, 34, + 131, 85, 50, 148, 193, 130, 92, 75, 60, 162, 220, 254 + ]); + // The point should have (in hex) + // P.x = 082aabae8b7dedb0e78aeb619ad3bfd9277a2f77ba7fad20ef6aab + // dc6c31d19ba5a6d12283553294c1825c4b3ca2dcfe + // P.y = 05b84ae5a942248eea39e1d91030458c40153f3b654ab7872d779a + // d1e942856a20c438e8d99bc8abfbf74729ce1f7ac8 + assert_eq!(p, from_coordinates_unchecked( + Fq::from_str("1256967425542823069694513550918025689490036478501181600525944653952846100887848729514132077573887342346961531624702").unwrap(), + Fq::from_str("880372082403694543476959909256504267215588055450016885103797700856746532134585942561958795215862304181527267736264").unwrap(), + Fq::one())); + } + + #[test] + fn test_hash_to_field_fq2() { + // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-J.10.1 + let dst = b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_"; + + { + // msg = + // u[0] = 03dbc2cce174e91ba93cbb08f26b917f98194a2ea08d1cce75b2b9 + // cc9f21689d80bd79b594a613d0a68eb807dfdc1cf8 + // + I * 05a2acec64114845711a54199ea339abd125ba38253b70a92c876d + // f10598bd1986b739cad67961eb94f7076511b3b39a + // u[1] = 02f99798e8a5acdeed60d7e18e9120521ba1f47ec090984662846b + // c825de191b5b7641148c0dbc237726a334473eee94 + // + I * 145a81e418d4010cc027a68f14391b30074e89e60ee7a22f87217b + // 2f6eb0c4b94c9115b436e6fa4607e95a98de30a435 + let msg = b""; + let (u0, u1) = hash_to_field_fq2(msg, dst); + assert_eq!( + u0, + Fq2{ + c0: Fq::from_str("593868448310005448561172252387029516360409945786457439875974315031640021389835649561235021338510064922970633805048").unwrap().0, + c1: Fq::from_str("867375309489067512797459860887365951877054038763818448057326190302701649888849997836339069389536967202878289851290").unwrap().0} + ); + assert_eq!( + u1, + Fq2{ + c0: Fq::from_str("457889704519948843474026022562641969443315715595459159112874498082953431971323809145630315884223143822925947137684").unwrap().0, + c1: Fq::from_str("3132697209754082586339430915081913810572071485832539443682634025529375380328136128542015469873094481703191673087029").unwrap().0} + ); + } + + { + // msg = abc + // u[0] = 15f7c0aa8f6b296ab5ff9c2c7581ade64f4ee6f1bf18f55179ff44 + // a2cf355fa53dd2a2158c5ecb17d7c52f63e7195771 + // + I * 01c8067bf4c0ba709aa8b9abc3d1cef589a4758e09ef53732d670f + // d8739a7274e111ba2fcaa71b3d33df2a3a0c8529dd + // u[1] = 187111d5e088b6b9acfdfad078c4dacf72dcd17ca17c82be35e79f + // 8c372a693f60a033b461d81b025864a0ad051a06e4 + // + I * 08b852331c96ed983e497ebc6dee9b75e373d923b729194af8e72a + // 051ea586f3538a6ebb1e80881a082fa2b24df9f566 + let msg = b"abc"; + let (u0, u1) = hash_to_field_fq2(msg, dst); + assert_eq!( + u0, + Fq2{ + c0: Fq::from_str("3381151350286428005095780827831774583653641216459357823974407145557165174365389989442078766443621078367363453769585").unwrap().0, + c1: Fq::from_str("274174695370444263853418070745339731640467919355184108253716879519695397069963034977795744692362177212201505728989").unwrap().0} + ); + assert_eq!( + u1, + Fq2{ + c0: Fq::from_str("3761918608077574755256083960277010506684793456226386707192711779006489497410866269311252402421709839991039401264868").unwrap().0, + c1: Fq::from_str("1342131492846344403298252211066711749849099599627623100864413228392326132610002371925674088601653350525231531947366").unwrap().0} + ); + } + } + + #[test] + fn test_hash_to_curve_g2() { + // Test vectors are from https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-J.10.1 + let dst = b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_"; + { + // msg = + // P.x = + // 0141ebfbdca40eb85b87142e130ab689c673cf60f1a3e98d69335266f30d9b8d4ac44c1038e9dcdd5393faf5c41fb78a + // + I * + // 05cb8437535e20ecffaef7752baddf98034139c38452458baeefab379ba13dff5bf5dd71b72418717047f5b0f37da03d + // P.y = + // 0503921d7f6a12805e72940b963c0cf3471c7b2a524950ca195d11062ee75ec076daf2d4bc358c4b190c0c98064fdd92 + // + I * + // 12424ac32561493f3fe3c260708a12b7c620e7be00099a974e259ddc7d1f6395c3c811cdd19f1e8dbf3e9ecfdcbab8d6 + let msg = b""; + let p_should_be = from_coordinates_unchecked_g2( + Fq2{ + c0: Fq::from_str("193548053368451749411421515628510806626565736652086807419354395577367693778571452628423727082668900187036482254730").unwrap().0, + c1: Fq::from_str("891930009643099423308102777951250899694559203647724988361022851024990473423938537113948850338098230396747396259901").unwrap().0 + }, + Fq2{ + c0: Fq::from_str("771717272055834152378281705972671257005357145478800908373659404991537354153455452961747174765859335819766715637138").unwrap().0, + c1: Fq::from_str("2810310118582126634041133454180705304393079139103252956502404531123692847658283858246402311867775854528543237781718").unwrap().0 + }, + Fq2::one() + ); + let p = hash_to_curve_g2(msg, dst); + assert_eq!(p, p_should_be); + } + { + // msg = abc + // P.x = 02c2d18e033b960562aae3cab37a27ce00d80ccd5ba4b7fe0e7a210245129dbec7780ccc7954725f4168aff2787776e6 + // + I * 139cddbccdc5e91b9623efd38c49f81a6f83f175e80b06fc374de9eb4b41dfe4ca3a230ed250fbe3a2acf73a41177fd8 + // P.y = 1787327b68159716a37440985269cf584bcb1e621d3a7202be6ea05c4cfe244aeb197642555a0645fb87bf7466b2ba48 + // + I * 00aa65dae3c8d732d10ecd2c50f8a1baf3001578f71c694e03866e9f3d49ac1e1ce70dd94a733534f106d4cec0eddd16 + let msg = b"abc"; + let p_should_be = from_coordinates_unchecked_g2( + Fq2{ + c0: Fq::from_str("424958340463073975547762735517193206833255107941790909009827635556634414746056077714431786321247871628515967727334").unwrap().0, + c1: Fq::from_str("3018679803970127877262826393814472528557413504329194740495363852840690589001358162447917674089074634504498585239512").unwrap().0 + }, + Fq2{ + c0: Fq::from_str("3621308185128395459888995526527127556614768604472132176060423302734876099689739385100475320409412954617897892887112").unwrap().0, + c1: Fq::from_str("102447784096837908713257069727879782642075240724579670654226801345708452018676587771714457671432122751958633012502").unwrap().0 + }, + Fq2::one() + ); + let p = hash_to_curve_g2(msg, dst); + assert_eq!(p, p_should_be); + } + { + // msg = abcdef0123456789 + // P.x = 121982811d2491fde9ba7ed31ef9ca474f0e1501297f68c298e9f4c0028add35aea8bb83d53c08cfc007c1e005723cd0 + // + I * 190d119345b94fbd15497bcba94ecf7db2cbfd1e1fe7da034d26cbba169fb3968288b3fafb265f9ebd380512a71c3f2c + // P.y = 05571a0f8d3c08d094576981f4a3b8eda0a8e771fcdcc8ecceaf1356a6acf17574518acb506e435b639353c2e14827c8 + // + I * 0bb5e7572275c567462d91807de765611490205a941a5a6af3b1691bfe596c31225d3aabdf15faff860cb4ef17c7c3be + let msg = b"abcdef0123456789"; + let p_should_be = from_coordinates_unchecked_g2( + Fq2{ + c0: Fq::from_str("2785790728239146617702443308248535381016035748520698399690132325213972292102741627498014391457605127656937478044880").unwrap().0, + c1: Fq::from_str("3855709393631831880910167818276435187147963371126198799654803099743427431977934703201153169947378798970358200024876").unwrap().0 + }, + Fq2{ + c0: Fq::from_str("821938378705205565995357931232097952117504537366318395539093959918654729488074273868834599496909844419980823111624").unwrap().0, + c1: Fq::from_str("1802420335575779950982935580421454302087567926385222707947527353462942499437987207287862072369052390195154530059198").unwrap().0 + }, + Fq2::one() + ); + let p = hash_to_curve_g2(msg, dst); + assert_eq!(p, p_should_be); + } + { + // msg = q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq + // P.x = 19a84dd7248a1066f737cc34502ee5555bd3c19f2ecdb3c7d9e24dc65d4e25e50d83f0f77105e955d78f4762d33c17da + // + I * 0934aba516a52d8ae479939a91998299c76d39cc0c035cd18813bec433f587e2d7a4fef038260eef0cef4d02aae3eb91 + // P.y = 14f81cd421617428bc3b9fe25afbb751d934a00493524bc4e065635b0555084dd54679df1536101b2c979c0152d09192 + // + I * 09bcccfa036b4847c9950780733633f13619994394c23ff0b32fa6b795844f4a0673e20282d07bc69641cee04f5e5662 + let msg = b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"; + let p_should_be = from_coordinates_unchecked_g2( + Fq2{ + c0: Fq::from_str("3949041098513688455491231180749724794697192943196730030853285011755806989731870696216017360514887069032515603535834").unwrap().0, + c1: Fq::from_str("1416893694506131976809002935212216317132941942570763849323065381335907430566747765697423320407614734575486820936593").unwrap().0 + }, + Fq2{ + c0: Fq::from_str("3227453710863835032992962605851449401391399355135442728893790186263669279022343042444878900124369614767241382891922").unwrap().0, + c1: Fq::from_str("1498738834073759871886466122933996764471889514532827927202777922460876335493588931070034160657995151627624577390178").unwrap().0 + }, + Fq2::one() + ); + let p = hash_to_curve_g2(msg, dst); + assert_eq!(p, p_should_be); + } + { + // msg = + // a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + // P.x = + // 01a6ba2f9a11fa5598b2d8ace0fbe0a0eacb65deceb476fbbcb64fd24557c2f4b18ecfc5663e54ae16a84f5ab7f62534 + // + I * + // 11fca2ff525572795a801eed17eb12785887c7b63fb77a42be46ce4a34131d71f7a73e95fee3f812aea3de78b4d01569 + // P.y = + // 0b6798718c8aed24bc19cb27f866f1c9effcdbf92397ad6448b5c9db90d2b9da6cbabf48adc1adf59a1a28344e79d57e + // + I * + // 03a47f8e6d1763ba0cad63d6114c0accbef65707825a511b251a660a9b3994249ae4e63fac38b23da0c398689ee2ab52 + let msg = b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + let p_should_be = from_coordinates_unchecked_g2( + Fq2{ + c0: Fq::from_str("254155017921606149907129844368549510385368618440139550318910532874259603395336903946742408725761795820224536519988").unwrap().0, + c1: Fq::from_str("2768431459296730426779166218544149791601585986233130583011501727704972362141149700714785450629498506208393873593705").unwrap().0 + }, + Fq2{ + c0: Fq::from_str("1755339344744337457318565116062025669984750617937721245220711425551575490663761638802010265668157125441634554205566").unwrap().0, + c1: Fq::from_str("560643043433789571968941329642646582974304556331567393300563909451776257854214387388500126524984624222885267024722").unwrap().0 + }, + Fq2::one() + ); + let p = hash_to_curve_g2(msg, dst); + assert_eq!(p, p_should_be); + } + } } From d662cd5d62a9ee5c0d23740578d2d66596393158 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 15 Jan 2024 10:32:41 +0100 Subject: [PATCH 40/53] hash_to_curve returns Result --- rust-bins/src/bin/keygen-genesis.rs | 14 +++++++------- rust-src/concordium_base/src/aggregate_sig/mod.rs | 10 +++++----- .../src/curve_arithmetic/arkworks_instances.rs | 15 +++++++++------ .../src/curve_arithmetic/ed25519_instance.rs | 9 +++++---- .../concordium_base/src/curve_arithmetic/mod.rs | 2 +- rust-src/concordium_base/src/id/id_verifier.rs | 6 ++++-- rust-src/concordium_base/src/id/types.rs | 10 ++++++---- 7 files changed, 37 insertions(+), 29 deletions(-) diff --git a/rust-bins/src/bin/keygen-genesis.rs b/rust-bins/src/bin/keygen-genesis.rs index 9003fb94a..4cd7e2f37 100644 --- a/rust-bins/src/bin/keygen-genesis.rs +++ b/rust-bins/src/bin/keygen-genesis.rs @@ -114,8 +114,8 @@ macro_rules! succeed_or_die { fn handle_generate_ar_keys(kgar: KeygenAr) -> Result<(), String> { let bytes_from_file = succeed_or_die!(fs::read(kgar.seed), e => "Could not read random input from provided file because {}"); - let generator = G1::hash_to_group(&bytes_from_file); - let key = G1::hash_to_group(&to_bytes(&generator)); + let generator = G1::hash_to_group(&bytes_from_file).expect("Hashing to curve expected to succeed"); + let key = G1::hash_to_group(&to_bytes(&generator)).expect("Hashing to curve expected to succeed"); let ar_public_key = PublicKey { generator, key }; let ar_identity = kgar.ar_identity; let name = kgar.name; @@ -184,15 +184,15 @@ fn handle_generate_ip_keys(kgip: KeygenIp) -> Result<(), String> { pub fn generate_ps_pk(n: u32, bytes: &[u8]) -> ps_sig::PublicKey { let mut ys: Vec = Vec::with_capacity(n as usize); let mut y_tildas: Vec = Vec::with_capacity(n as usize); - let mut g1_element = G1::hash_to_group(bytes); - let mut g2_element = G2::hash_to_group(&to_bytes(&g1_element)); + let mut g1_element = G1::hash_to_group(bytes).expect("Hashing to curve expected to succeed"); + let mut g2_element = G2::hash_to_group(&to_bytes(&g1_element)).expect("Hashing to curve expected to succeed"); for _ in 0..n { ys.push(g1_element); y_tildas.push(g2_element); - g1_element = G1::hash_to_group(&to_bytes(&g2_element)); - g2_element = G2::hash_to_group(&to_bytes(&g1_element)); + g1_element = G1::hash_to_group(&to_bytes(&g2_element)).expect("Hashing to curve expected to succeed"); + g2_element = G2::hash_to_group(&to_bytes(&g1_element)).expect("Hashing to curve expected to succeed"); } - let x_tilda = G2::hash_to_group(&to_bytes(&g2_element)); + let x_tilda = G2::hash_to_group(&to_bytes(&g2_element)).expect("Hashing to curve expected to succeed"); ps_sig::PublicKey { g: G1::one_point(), g_tilda: G2::one_point(), diff --git a/rust-src/concordium_base/src/aggregate_sig/mod.rs b/rust-src/concordium_base/src/aggregate_sig/mod.rs index a965dec1a..039392763 100644 --- a/rust-src/concordium_base/src/aggregate_sig/mod.rs +++ b/rust-src/concordium_base/src/aggregate_sig/mod.rs @@ -31,7 +31,7 @@ impl SecretKey

{ /// Sign a message using the SecretKey pub fn sign(&self, m: &[u8]) -> Signature

{ - let g1_hash = P::G1::hash_to_group(m); + let g1_hash = P::G1::hash_to_group(m).expect("Hashing to curve expected to succeed"); let signature = g1_hash.mul_by_scalar(&self.0); Signature(signature) } @@ -84,7 +84,7 @@ impl PublicKey

{ /// For now, the generator used is the default generator of the underlying /// library however, this should be parametrized in the future pub fn verify(&self, m: &[u8], signature: Signature

) -> bool { - let g1_hash = P::G1::hash_to_group(m); + let g1_hash = P::G1::hash_to_group(m).expect("Hashing to curve expected to succeed"); // compute pairings in parallel P::check_pairing_eq(&signature.0, &P::G2::one_point(), &g1_hash, &self.0) } @@ -160,7 +160,7 @@ pub fn verify_aggregate_sig( let product = m_pk_pairs .par_iter() .fold(::one, |prod, (m, pk)| { - let g1_hash = P::G1::hash_to_group(m); + let g1_hash = P::G1::hash_to_group(m).expect("Hashing to curve expected to succeed"); let paired = P::pair(&g1_hash, &pk.0); let mut p = prod; p.mul_assign(&paired); @@ -211,7 +211,7 @@ pub fn verify_aggregate_sig_hybrid( .fold(P::G2::zero_point, |s, x| s.plus_point(&x.0)) .reduce(P::G2::zero_point, |s, x| s.plus_point(&x)) }; - let g1_hash = P::G1::hash_to_group(m); + let g1_hash = P::G1::hash_to_group(m).expect("Hashing to curve expected to succeed"); let paired = P::pair(&g1_hash, &sum_pk_i); let mut p = prod; p.mul_assign(&paired); @@ -255,7 +255,7 @@ pub fn verify_aggregate_sig_trusted_keys( P::check_pairing_eq( &signature.0, &P::G2::one_point(), - &P::G1::hash_to_group(m), + &P::G1::hash_to_group(m).expect("Hashing to curve expected to succeed"), &sum, ) } diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 62e0d5388..a06d17cc8 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -2,7 +2,7 @@ //! `arkworks` field/curve traits. use super::{Curve, CurveDecodingError, Field, GenericMultiExp, PrimeField}; use crate::common::{Deserial, Serial, Serialize}; -use ark_ec::hashing::HashToCurve; +use ark_ec::hashing::{HashToCurve, HashToCurveError}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use core::fmt; @@ -115,6 +115,10 @@ impl Deserial for ArkGroup { } } +impl From for CurveDecodingError { + fn from(_value: HashToCurveError) -> Self { CurveDecodingError::NotOnCurve } +} + /// Curve configuration. /// /// These parameters cannot be taken from the `arkworks` traits. Each `arkworks` @@ -193,10 +197,9 @@ where .expect("The scalar with top two bits erased should be valid.") } - fn hash_to_group(m: &[u8]) -> Self { - let hasher = G::Hasher::new(G::DOMAIN_STRING.as_ref()) - .expect("Expected valid domain separation string"); - let res = G::Hasher::hash(&hasher, m).expect("Expected successful hashing to curve"); - ArkGroup(res.into()) + fn hash_to_group(m: &[u8]) -> Result { + let hasher = G::Hasher::new(G::DOMAIN_STRING.as_ref())?; + let res = G::Hasher::hash(&hasher, m)?; + Ok(ArkGroup(res.into())) } } diff --git a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs index 7bc2bac20..f68e80f93 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/ed25519_instance.rs @@ -1,4 +1,4 @@ -use super::{field_adapters::FFField, Curve, Field, MultiExp, PrimeField}; +use super::{field_adapters::FFField, Curve, CurveDecodingError, Field, MultiExp, PrimeField}; use crate::common::{Buffer, Deserial, Serial}; use byteorder::{ByteOrder, LittleEndian}; use curve25519_dalek::{ @@ -8,8 +8,7 @@ use curve25519_dalek::{ traits::{Identity, VartimeMultiscalarMul, VartimePrecomputedMultiscalarMul}, }; use sha2::Sha512; - -use std::borrow::Borrow; +use std::{borrow::Borrow, result::Result}; impl Serial for Scalar { fn serial(&self, out: &mut B) { @@ -140,7 +139,9 @@ impl Curve for RistrettoPoint { .expect("The scalar with top two bits erased should be valid.") } - fn hash_to_group(m: &[u8]) -> Self { RistrettoPoint::hash_from_bytes::(m) } + fn hash_to_group(m: &[u8]) -> Result { + Result::Ok(RistrettoPoint::hash_from_bytes::(m)) + } } /// An instance of multiexp algorithm from the Dalek library that uses diff --git a/rust-src/concordium_base/src/curve_arithmetic/mod.rs b/rust-src/concordium_base/src/curve_arithmetic/mod.rs index ee6f4d7d3..c2ffcbc52 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/mod.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/mod.rs @@ -156,7 +156,7 @@ pub trait Curve: /// them as a little-endian integer. fn scalar_from_bytes>(bs: A) -> Self::Scalar; /// Hash to a curve point from a seed. This is deterministic function. - fn hash_to_group(m: &[u8]) -> Self; + fn hash_to_group(m: &[u8]) -> Result; } /// An abstraction over a multiexp algorithm. diff --git a/rust-src/concordium_base/src/id/id_verifier.rs b/rust-src/concordium_base/src/id/id_verifier.rs index 7ee789368..a89633f17 100644 --- a/rust-src/concordium_base/src/id/id_verifier.rs +++ b/rust-src/concordium_base/src/id/id_verifier.rs @@ -358,7 +358,8 @@ mod tests { let pub_data = cred_data.get_cred_key_info(); - let reg_id: G1 = Curve::hash_to_group(b"some_bytes"); + let reg_id: G1 = + Curve::hash_to_group(b"some_bytes").expect("Hashing to curve expected to succeed"); let account_address = account_address_from_registration_id(®_id); let challenge = b"13549686546546546854651357687354"; @@ -533,7 +534,8 @@ mod tests { #[test] fn test_verify_id_attributes_proofs() { - let point: G1 = Curve::hash_to_group(b"some_bytes"); + let point: G1 = + Curve::hash_to_group(b"some_bytes").expect("Hashing to curve expected to succeed"); let cmm_prf = Commitment(point); let cmm_max_accounts = Commitment(point); let cmm_cred_counter = Commitment(point); diff --git a/rust-src/concordium_base/src/id/types.rs b/rust-src/concordium_base/src/id/types.rs index 0b5ede72e..face43556 100644 --- a/rust-src/concordium_base/src/id/types.rs +++ b/rust-src/concordium_base/src/id/types.rs @@ -1895,19 +1895,21 @@ impl GlobalContext { /// amount, and a fixed seed. pub fn generate_from_seed(genesis_string: String, n: usize, seed: &[u8]) -> Self { // initialize the first generator from pi digits. - let g = C::hash_to_group(seed); + let g = C::hash_to_group(seed).expect("Hashing to curve expected to succeed"); // generate next generator by hashing the previous one - let h = C::hash_to_group(&to_bytes(&g)); + let h = C::hash_to_group(&to_bytes(&g)).expect("Hashing to curve expected to succeed"); let cmm_key = PedersenKey { g, h }; let mut generators = Vec::with_capacity(n); let mut generator = h; for _ in 0..n { - generator = C::hash_to_group(&to_bytes(&generator)); + generator = C::hash_to_group(&to_bytes(&generator)) + .expect("Hashing to curve expected to succeed"); let g = generator; - generator = C::hash_to_group(&to_bytes(&generator)); + generator = C::hash_to_group(&to_bytes(&generator)) + .expect("Hashing to curve expected to succeed"); let h = generator; generators.push((g, h)); } From 627de2cad14d20cc4db0c65cb3d88369e9a5e6d9 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 15 Jan 2024 11:11:21 +0100 Subject: [PATCH 41/53] Formatting --- rust-bins/src/bin/keygen-genesis.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/rust-bins/src/bin/keygen-genesis.rs b/rust-bins/src/bin/keygen-genesis.rs index 4cd7e2f37..927d1a950 100644 --- a/rust-bins/src/bin/keygen-genesis.rs +++ b/rust-bins/src/bin/keygen-genesis.rs @@ -114,8 +114,10 @@ macro_rules! succeed_or_die { fn handle_generate_ar_keys(kgar: KeygenAr) -> Result<(), String> { let bytes_from_file = succeed_or_die!(fs::read(kgar.seed), e => "Could not read random input from provided file because {}"); - let generator = G1::hash_to_group(&bytes_from_file).expect("Hashing to curve expected to succeed"); - let key = G1::hash_to_group(&to_bytes(&generator)).expect("Hashing to curve expected to succeed"); + let generator = + G1::hash_to_group(&bytes_from_file).expect("Hashing to curve expected to succeed"); + let key = + G1::hash_to_group(&to_bytes(&generator)).expect("Hashing to curve expected to succeed"); let ar_public_key = PublicKey { generator, key }; let ar_identity = kgar.ar_identity; let name = kgar.name; @@ -185,14 +187,18 @@ pub fn generate_ps_pk(n: u32, bytes: &[u8]) -> ps_sig::PublicKey { let mut ys: Vec = Vec::with_capacity(n as usize); let mut y_tildas: Vec = Vec::with_capacity(n as usize); let mut g1_element = G1::hash_to_group(bytes).expect("Hashing to curve expected to succeed"); - let mut g2_element = G2::hash_to_group(&to_bytes(&g1_element)).expect("Hashing to curve expected to succeed"); + let mut g2_element = + G2::hash_to_group(&to_bytes(&g1_element)).expect("Hashing to curve expected to succeed"); for _ in 0..n { ys.push(g1_element); y_tildas.push(g2_element); - g1_element = G1::hash_to_group(&to_bytes(&g2_element)).expect("Hashing to curve expected to succeed"); - g2_element = G2::hash_to_group(&to_bytes(&g1_element)).expect("Hashing to curve expected to succeed"); + g1_element = G1::hash_to_group(&to_bytes(&g2_element)) + .expect("Hashing to curve expected to succeed"); + g2_element = G2::hash_to_group(&to_bytes(&g1_element)) + .expect("Hashing to curve expected to succeed"); } - let x_tilda = G2::hash_to_group(&to_bytes(&g2_element)).expect("Hashing to curve expected to succeed"); + let x_tilda = + G2::hash_to_group(&to_bytes(&g2_element)).expect("Hashing to curve expected to succeed"); ps_sig::PublicKey { g: G1::one_point(), g_tilda: G2::one_point(), From 15ccdf185d1aeb7e109d5741c132d7dae1a3df7f Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 15 Jan 2024 13:20:11 +0100 Subject: [PATCH 42/53] Apply suggestions from code review Co-authored-by: Hamidreza <54936533+hamiidreza@users.noreply.github.com> --- rust-src/concordium_base/src/ecvrf/proof.rs | 7 ++++--- rust-src/concordium_base/src/ecvrf/public.rs | 4 ++-- rust-src/concordium_base/src/ecvrf/secret.rs | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/rust-src/concordium_base/src/ecvrf/proof.rs b/rust-src/concordium_base/src/ecvrf/proof.rs index 6b4368fa0..04ad90b45 100644 --- a/rust-src/concordium_base/src/ecvrf/proof.rs +++ b/rust-src/concordium_base/src/ecvrf/proof.rs @@ -29,7 +29,8 @@ pub fn hash_points(pts: &[CompressedEdwardsY]) -> Scalar { /// a given public key. pub struct Proof(pub EdwardsPoint, pub Scalar, pub Scalar); -/// Implements step 8 of +/// Implements step 8 of + /// i.e. transforms a proof to a byte string impl Serial for Proof { #[inline] @@ -48,7 +49,7 @@ impl Serial for Proof { } } -/// Implements +/// Implements /// Construct a `Proof` from a slice of bytes. This function always /// results in a valid proof object. impl Deserial for Proof { @@ -80,7 +81,7 @@ impl Debug for Proof { } } -/// Implements +/// Implements impl Proof { pub fn to_hash(&self) -> [u8; 64] { let p = self.0.mul_by_cofactor(); diff --git a/rust-src/concordium_base/src/ecvrf/public.rs b/rust-src/concordium_base/src/ecvrf/public.rs index abafbbd0d..ae92164f0 100644 --- a/rust-src/concordium_base/src/ecvrf/public.rs +++ b/rust-src/concordium_base/src/ecvrf/public.rs @@ -82,7 +82,7 @@ impl PublicKey { #[inline] pub fn as_bytes(&self) -> &'_ [u8; PUBLIC_KEY_LENGTH] { &(self.0).0 } - /// Implements + /// Implements /// The failure should not happen in practice, expected number of iterations /// is 2. // TODO: Check whether it still implements the algorithm after the RFC draft was @@ -117,7 +117,7 @@ impl PublicKey { pub fn verify_key(&self) -> bool { !self.1.is_small_order() } - /// Implements + /// Implements #[allow(clippy::many_single_char_names)] pub fn verify(&self, pi: &Proof, message: &[u8]) -> bool { if let Some(h) = self.hash_to_curve(message) { diff --git a/rust-src/concordium_base/src/ecvrf/secret.rs b/rust-src/concordium_base/src/ecvrf/secret.rs index 7b5a10349..77469b883 100644 --- a/rust-src/concordium_base/src/ecvrf/secret.rs +++ b/rust-src/concordium_base/src/ecvrf/secret.rs @@ -136,7 +136,7 @@ use super::proof::*; impl ExpandedSecretKey { /// VRF proof with expanded secret key - /// Implements + /// Implements pub fn prove(&self, public_key: &PublicKey, alpha: &[u8]) -> Proof { let x = self.key; let h = public_key @@ -159,7 +159,7 @@ impl ExpandedSecretKey { Proof(gamma, c, k_plus_cx) } - /// Implements + /// Implements fn nonce_generation(&self, h_string: &[u8]) -> Scalar { let digest = Sha512::new() .chain_update(self.nonce) From a3fdb7aa7947bebbbac3b4abdf4dfbac19e96d9a Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 15 Jan 2024 13:35:45 +0100 Subject: [PATCH 43/53] Remove todo; fix formatting in comments --- rust-src/concordium_base/src/ecvrf/proof.rs | 3 +-- rust-src/concordium_base/src/ecvrf/public.rs | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/rust-src/concordium_base/src/ecvrf/proof.rs b/rust-src/concordium_base/src/ecvrf/proof.rs index 04ad90b45..fc63bc41a 100644 --- a/rust-src/concordium_base/src/ecvrf/proof.rs +++ b/rust-src/concordium_base/src/ecvrf/proof.rs @@ -29,8 +29,7 @@ pub fn hash_points(pts: &[CompressedEdwardsY]) -> Scalar { /// a given public key. pub struct Proof(pub EdwardsPoint, pub Scalar, pub Scalar); -/// Implements step 8 of - +/// Implements step 8 of /// i.e. transforms a proof to a byte string impl Serial for Proof { #[inline] diff --git a/rust-src/concordium_base/src/ecvrf/public.rs b/rust-src/concordium_base/src/ecvrf/public.rs index ae92164f0..56e36c4c0 100644 --- a/rust-src/concordium_base/src/ecvrf/public.rs +++ b/rust-src/concordium_base/src/ecvrf/public.rs @@ -85,8 +85,6 @@ impl PublicKey { /// Implements /// The failure should not happen in practice, expected number of iterations /// is 2. - // TODO: Check whether it still implements the algorithm after the RFC draft was - // converted to a "stable" RFC version. pub fn hash_to_curve(&self, message: &[u8]) -> Option { let mut p_candidate_bytes = [0u8; 32]; let mut h: Sha512 = Sha512::new(); From a3f83ead8369f7a64f5839f9898f948936af4025 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 15 Jan 2024 13:48:34 +0100 Subject: [PATCH 44/53] Resolved comments after review --- rust-src/concordium_base/benches/eddsa_benchmarks.rs | 8 ++++---- rust-src/ed25519_hd_key_derivation/src/lib.rs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rust-src/concordium_base/benches/eddsa_benchmarks.rs b/rust-src/concordium_base/benches/eddsa_benchmarks.rs index a626e4bef..70fc42fea 100644 --- a/rust-src/concordium_base/benches/eddsa_benchmarks.rs +++ b/rust-src/concordium_base/benches/eddsa_benchmarks.rs @@ -28,10 +28,10 @@ pub fn bench_sign(c: &mut Criterion) { } let d = a.clone(); - let signing = SigningKey::generate(&mut csprng); - let pk = signing.verifying_key(); - let sig = signing.sign(a.as_slice()); - c.bench_function("sign {}", move |b| b.iter(|| signing.sign(a.as_slice()))); + let signing_key = SigningKey::generate(&mut csprng); + let pk = signing_key.verifying_key(); + let sig = signing_key.sign(a.as_slice()); + c.bench_function("sign {}", move |b| b.iter(|| signing_key.sign(a.as_slice()))); c.bench_function("verify{}", move |b| { b.iter(|| pk.verify(d.as_slice(), &sig)) }); diff --git a/rust-src/ed25519_hd_key_derivation/src/lib.rs b/rust-src/ed25519_hd_key_derivation/src/lib.rs index 0612a2811..e1b1ed554 100644 --- a/rust-src/ed25519_hd_key_derivation/src/lib.rs +++ b/rust-src/ed25519_hd_key_derivation/src/lib.rs @@ -179,7 +179,7 @@ pub fn derive_from_parsed_path(parsed_path: &[u32], seed: &[u8]) -> Result Date: Mon, 15 Jan 2024 13:55:12 +0100 Subject: [PATCH 45/53] formatting --- rust-src/concordium_base/benches/eddsa_benchmarks.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rust-src/concordium_base/benches/eddsa_benchmarks.rs b/rust-src/concordium_base/benches/eddsa_benchmarks.rs index 70fc42fea..8fb3240c2 100644 --- a/rust-src/concordium_base/benches/eddsa_benchmarks.rs +++ b/rust-src/concordium_base/benches/eddsa_benchmarks.rs @@ -31,7 +31,9 @@ pub fn bench_sign(c: &mut Criterion) { let signing_key = SigningKey::generate(&mut csprng); let pk = signing_key.verifying_key(); let sig = signing_key.sign(a.as_slice()); - c.bench_function("sign {}", move |b| b.iter(|| signing_key.sign(a.as_slice()))); + c.bench_function("sign {}", move |b| { + b.iter(|| signing_key.sign(a.as_slice())) + }); c.bench_function("verify{}", move |b| { b.iter(|| pk.verify(d.as_slice(), &sig)) }); From 4c92b913440a5bd9edf2917b087a818f22f5d4d2 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Mon, 15 Jan 2024 15:49:41 +0100 Subject: [PATCH 46/53] Move hash-to-curve to a separate module; document discrepancies between our previous custom implementation and the current arkworks implementation --- .../curve_arithmetic/bls12_381_arkworks.rs | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 4a1bd62d7..3f874b979 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -152,23 +152,18 @@ impl fmt::Display for ArkField { } } +/// Tess for serialization/deserialization and conversion to/from bigint +/// representation. #[cfg(test)] mod tests { - use std::str::FromStr; - use super::*; use crate::{ common::*, curve_arithmetic::{Curve, Field, PrimeField}, }; - use ark_ec::hashing::HashToCurve; - use ark_ff::field_hashers::HashToField; use num_bigint::BigUint; - use num_traits::One; use rand::thread_rng; - type Fq = ArkField; - const SCALAR_BYTES_LE: [u8; 32] = [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, @@ -271,20 +266,37 @@ mod tests { type G1 = ArkGroup; type G2 = ArkGroup; - fn from_coordinates_unchecked(x: Fq, y: Fq, z: Fq) -> G1 { - G1Projective::new_unchecked(x.0, y.0, z.0).into() - } - - fn from_coordinates_unchecked_g2(x: Fq2, y: Fq2, z: Fq2) -> G2 { - G2Projective::new_unchecked(x, y, z).into() - } - macro_test_scalar_byte_conversion!(sc_bytes_conv_g1, G1); macro_test_scalar_byte_conversion!(sc_bytes_conv_g2, G2); macro_test_scalar_byte_conversion!(sc_bytes_conv_bls12, Bls12); macro_test_group_byte_conversion!(curve_bytes_conv_g1, G1); macro_test_group_byte_conversion!(curve_bytes_conv_g2, G2); +} + +/// Test for hashig arbitrary bytes to curve. The tests were ported from the +/// custom implementation that was replaced with the `arkworks` +/// `MapToCurveBasedHasher` implementation instantiated with the `G1` and `G2` +/// groups on `BLS12-381`. +#[cfg(test)] +mod hash_to_curve_tests { + // Note that that the old custom implementation refers to https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10. + // However, `ark-ec` v.0.4.0 https://docs.rs/ark-ec/0.4.0/src/ark_ec/hashing/map_to_curve_hasher.rs.html#48 refers + // to the previous version of the draft. Both drafts describe the same + // algorithms and use the same test vectors for the BLS curve. Test vectors + // of the v9 of the draft can be found in Appendix H.9.1 https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-09#section-h.9.1 and + // H.10.1 https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-09#section-h.10.1 + + use super::*; + use crate::{common::*, curve_arithmetic::Field}; + use ark_ec::hashing::HashToCurve; + use ark_ff::field_hashers::HashToField; + use num_traits::One; + use std::str::FromStr; + + type G1 = ArkGroup; + type G2 = ArkGroup; + type Fq = ArkField; fn hash_to_curve(msg: &[u8], dst: &[u8]) -> G1 { let hasher = >::Hasher::new(dst) @@ -308,6 +320,14 @@ mod tests { (fs[0], fs[1]) } + fn from_coordinates_unchecked(x: Fq, y: Fq, z: Fq) -> G1 { + G1Projective::new_unchecked(x.0, y.0, z.0).into() + } + + fn from_coordinates_unchecked_g2(x: Fq2, y: Fq2, z: Fq2) -> G2 { + G2Projective::new_unchecked(x, y, z).into() + } + // This tests the function hash_to_curve function according to // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-J.9.1 with // suite = BLS12381G1_XMD:SHA-256_SSWU_RO_ From 383fb5d31c84f7dc11d02d3abdf4fdc60c57df4e Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Wed, 17 Jan 2024 12:53:11 +0100 Subject: [PATCH 47/53] Cleanup --- rust-src/concordium_base/src/id/constants.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/rust-src/concordium_base/src/id/constants.rs b/rust-src/concordium_base/src/id/constants.rs index 1aa95dbe3..0dea25dd3 100644 --- a/rust-src/concordium_base/src/id/constants.rs +++ b/rust-src/concordium_base/src/id/constants.rs @@ -27,7 +27,6 @@ pub type IpPairing = Bls12; /// Field used by the identity provider and anonymity revoker. /// This is the scalar field of both the ArCurve and the IpPairing. pub type BaseField = ::ScalarField; -// pub type BaseField = ArkField; /// Index used to create the RegId of the initial credential. pub const INITIAL_CREDENTIAL_INDEX: u8 = 0; From c8fb2fc071cd7618e536d577ebb94ce135314337 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Wed, 17 Jan 2024 16:41:17 +0100 Subject: [PATCH 48/53] Fix scalar_from_bytes: ensure that there is always right number of limbs (possibly filled with zeros); document restrictions on CAPACITY --- .../src/curve_arithmetic/arkworks_instances.rs | 12 +++++++----- .../src/curve_arithmetic/bls12_381_arkworks.rs | 2 +- rust-src/concordium_base/src/curve_arithmetic/mod.rs | 4 +++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index a06d17cc8..3b8decf8a 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -178,11 +178,11 @@ where fn scalar_from_bytes>(bs: A) -> Self::Scalar { // Traverse at most `ceil(CAPACITY / 8)` 8-byte chunks. let s = num::integer::div_ceil(Self::Scalar::CAPACITY, 8); - let mut fr = Vec::with_capacity(s as usize); - for chunk in bs.as_ref().chunks(8).take(s as usize) { + let mut fr = vec![0u64; s as usize]; + for (chunk, place) in bs.as_ref().chunks(8).take(s as usize).zip(&mut fr) { let mut v = [0u8; 8]; v[..chunk.len()].copy_from_slice(chunk); - fr.push(u64::from_le_bytes(v)); + *place = u64::from_le_bytes(v); } let total_size_in_bits = bs.as_ref().len() * 8; let num_bits_to_remove = total_size_in_bits as u32 - Self::Scalar::CAPACITY; @@ -193,8 +193,10 @@ where let mask = u64::MAX >> num_bits_to_remove; // unset `num_bits_to_remove` topmost bits in the last u64. *fr.last_mut().expect("Non empty vector expected") &= mask; - ::from_repr(&fr) - .expect("The scalar with top two bits erased should be valid.") + ::from_repr(&fr).expect(&format!( + "The scalar with top {:} bits erased should be valid.", + num_bits_to_remove + )) } fn hash_to_group(m: &[u8]) -> Result { diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 3f874b979..9b7d52f41 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -169,7 +169,7 @@ mod tests { 0, 0, 0, 0, 0, 0, 0, ]; - /// Check that scalar_from_bytes_helper works on small values. + /// Check that scalar_from_bytes works on small values. #[test] fn scalar_from_bytes_small() { let mut rng = rand::thread_rng(); diff --git a/rust-src/concordium_base/src/curve_arithmetic/mod.rs b/rust-src/concordium_base/src/curve_arithmetic/mod.rs index c2ffcbc52..5d3e7025b 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/mod.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/mod.rs @@ -87,7 +87,9 @@ pub trait PrimeField: Field { const NUM_BITS: u32; /// How many bits of information can be reliably stored in the field - /// element. + /// element. It is expected that `num_limbs * 64 - CAPACITY < 64`, where + /// `num_limbs` is the size of vector returned by + /// `PrimeField::into_repr(self)`. const CAPACITY: u32; /// Get a big integer representation with least significant digit first. From e98c19e1547579515318fa5c7edf55e817b5da46 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Wed, 17 Jan 2024 16:58:44 +0100 Subject: [PATCH 49/53] Clippy --- .../src/curve_arithmetic/arkworks_instances.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 3b8decf8a..abd1fa7f8 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -193,10 +193,12 @@ where let mask = u64::MAX >> num_bits_to_remove; // unset `num_bits_to_remove` topmost bits in the last u64. *fr.last_mut().expect("Non empty vector expected") &= mask; - ::from_repr(&fr).expect(&format!( - "The scalar with top {:} bits erased should be valid.", - num_bits_to_remove - )) + ::from_repr(&fr).unwrap_or_else(|_| { + panic!( + "The scalar with top {:} bits erased should be valid.", + num_bits_to_remove + ) + }) } fn hash_to_group(m: &[u8]) -> Result { From 0d59c2e0d468b3841414ef22fc16070de4999eb2 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Wed, 17 Jan 2024 20:01:53 +0100 Subject: [PATCH 50/53] Fix scalar_from_bytes: number of chunks was computed wrong --- .../src/curve_arithmetic/arkworks_instances.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index abd1fa7f8..711703b14 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -176,8 +176,8 @@ where fn scalar_from_u64(n: u64) -> Self::Scalar { ArkField(G::ScalarField::from(n)) } fn scalar_from_bytes>(bs: A) -> Self::Scalar { - // Traverse at most `ceil(CAPACITY / 8)` 8-byte chunks. - let s = num::integer::div_ceil(Self::Scalar::CAPACITY, 8); + // Traverse at most `ceil(CAPACITY / 64)` 8-byte chunks. + let s = num::integer::div_ceil(Self::Scalar::CAPACITY, 64); let mut fr = vec![0u64; s as usize]; for (chunk, place) in bs.as_ref().chunks(8).take(s as usize).zip(&mut fr) { let mut v = [0u8; 8]; @@ -195,8 +195,8 @@ where *fr.last_mut().expect("Non empty vector expected") &= mask; ::from_repr(&fr).unwrap_or_else(|_| { panic!( - "The scalar with top {:} bits erased should be valid.", - num_bits_to_remove + "The scalar {:?} with top {:} bits erased should be valid.", + fr, num_bits_to_remove ) }) } From cf3768f2ed69122740cf3a81434324085fc01620 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 18 Jan 2024 10:49:13 +0100 Subject: [PATCH 51/53] Fix total_size_in_bits in scalar_from_bytes: now it's calculated from the number of chuncks, not from the imput size. Add more tests --- .../curve_arithmetic/arkworks_instances.rs | 10 +- .../curve_arithmetic/bls12_381_arkworks.rs | 114 ++++++++++++++++-- 2 files changed, 109 insertions(+), 15 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs index 711703b14..093f4a97d 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/arkworks_instances.rs @@ -177,15 +177,15 @@ where fn scalar_from_bytes>(bs: A) -> Self::Scalar { // Traverse at most `ceil(CAPACITY / 64)` 8-byte chunks. - let s = num::integer::div_ceil(Self::Scalar::CAPACITY, 64); - let mut fr = vec![0u64; s as usize]; - for (chunk, place) in bs.as_ref().chunks(8).take(s as usize).zip(&mut fr) { + let num_chunks = num::integer::div_ceil(Self::Scalar::CAPACITY, 64); + let mut fr = vec![0u64; num_chunks as usize]; + for (chunk, place) in bs.as_ref().chunks(8).take(num_chunks as usize).zip(&mut fr) { let mut v = [0u8; 8]; v[..chunk.len()].copy_from_slice(chunk); *place = u64::from_le_bytes(v); } - let total_size_in_bits = bs.as_ref().len() * 8; - let num_bits_to_remove = total_size_in_bits as u32 - Self::Scalar::CAPACITY; + let total_size_in_bits = num_chunks * 64; + let num_bits_to_remove = total_size_in_bits - Self::Scalar::CAPACITY; // create a mask for the last chunk with the topmost `num_bits_to_remove` zeros // followed by `CAPACITY` of ones; it's implemented using (logical) right shift // that adds zeros from the left. E.g. if `num_bits_to_remove = 2`, the diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 9b7d52f41..4bfc88a16 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -162,13 +162,80 @@ mod tests { curve_arithmetic::{Curve, Field, PrimeField}, }; use num_bigint::BigUint; - use rand::thread_rng; + use rand::{thread_rng, Rng, RngCore}; + + type G1 = ArkGroup; + type G2 = ArkGroup; const SCALAR_BYTES_LE: [u8; 32] = [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, ]; + const SCALAR_BYTES_LE_SHORT: [u8; 30] = [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 0, + 0, 0, 0, 0, 255, + ]; + + const SCALAR_BYTES_LE_LONG: [u8; 33] = [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 0, + 0, 0, 0, 0, 0, 0, 0, 255, + ]; + + /// Test that if the size of the input array to `scalar_from_bytes()` is + /// less than 32, extra zeros are added at the end of the array to extend it + /// to 32 bytes. + #[test] + fn scalar_from_bytes_short() { + let s = ::scalar_from_bytes(&SCALAR_BYTES_LE_SHORT); + let limbs: Vec = s.into_repr(); + // Convert limbs into an array of bytes + let mut buffer = Vec::with_capacity(32); + for u in limbs { + buffer.extend(u.to_le_bytes()); + } + let bytes: [u8; 32] = buffer + .try_into() + .expect("Expected a bytes array of size 32"); + let mut expected = [0u8; 32]; + // fill the fist bytes with the input, remainig bytes will be zeroes. + expected[..30].copy_from_slice(&SCALAR_BYTES_LE_SHORT); + assert_eq!(expected, bytes) + } + + /// Test that if the size of the input array to `scalar_from_bytes()` is + /// greater than 32, the extra bytes are ignored. + #[test] + fn scalar_from_bytes_long() { + let s = ::scalar_from_bytes(&SCALAR_BYTES_LE_LONG); + let fits_capacity_limbs: Vec = s.into_repr(); + // Create four u64 limbs of the scalar representation from the first 32 bytes + let mut limbs_from_long = [0u64; 4]; + let mut buffer = [0u8; 32]; + buffer.copy_from_slice(&SCALAR_BYTES_LE_LONG[..32]); + for (i, chunk) in buffer.as_ref().chunks(8).take(4).enumerate() { + let mut v = [0u8; 8]; + v[..chunk.len()].copy_from_slice(chunk); + limbs_from_long[i] = u64::from_le_bytes(v); + } + compare_up_to_last_two_bits(&limbs_from_long, &fits_capacity_limbs) + } + + /// Compare the limbs masking the last limb of the first argument. + /// The second agument is assumed to be obtained from `scalar_from_bytes`, + /// so it is always capped by CAPACITY + fn compare_up_to_last_two_bits(limbs: &[u64], fits_capacity_limbs: &[u64]) { + let mask = !(1u64 << 63 | 1u64 << 62); + assert_eq!(limbs[0], fits_capacity_limbs[0], "First limb."); + assert_eq!(limbs[1], fits_capacity_limbs[1], "Second limb."); + assert_eq!(limbs[2], fits_capacity_limbs[2], "Third limb."); + assert_eq!( + limbs[3] & mask, + fits_capacity_limbs[3], + "Fourth limb with top bit masked." + ); + } + /// Check that scalar_from_bytes works on small values. #[test] fn scalar_from_bytes_small() { @@ -177,15 +244,44 @@ mod tests { let n = >::random(&mut rng); let mut bytes = to_bytes(&n); bytes.reverse(); - let m = as Curve>::scalar_from_bytes(&bytes); + let m = ::scalar_from_bytes(&bytes); // make sure that n and m only differ in the topmost bit. let n = n.into_repr(); let m = m.into_repr(); - let mask = !(1u64 << 63 | 1u64 << 62); - assert_eq!(n[0], m[0], "First limb."); - assert_eq!(n[1], m[1], "Second limb."); - assert_eq!(n[2], m[2], "Third limb."); - assert_eq!(n[3] & mask, m[3] & mask, "Fourth limb with top bit masked."); + compare_up_to_last_two_bits(&n, &m); + } + } + + // Test that everything that exeeds `CAPACITY` is ignored + /// by `Curve::scalar_from_bytes()` + #[test] + fn test_scalar_from_bytes_big() { + let mut rng = rand::thread_rng(); + for _ in 0..1000 { + // First, we generate 31 random bytes. + let mut lower_bytes: [u8; 31] = [0u8; 31]; + rng.fill_bytes(&mut lower_bytes); + let mut fits_capacity_bytes = [0u8; 32]; + // Next, we create a byte array that is filled with random lower bytes, the last + // byte is in [0; 63], that is, of the form 0b00XXXXXX (big-endian). + fits_capacity_bytes[0..31].copy_from_slice(&lower_bytes); + let n = rng.gen_range(0..63); + fits_capacity_bytes[31] = n; + let fits_capacity = ::scalar_from_bytes(fits_capacity_bytes); + let i = rng.gen_range(1..4); + // Now, we create a byte array from lower bytes with the last byte being number + // that is guaranteed to exceed `G1::Scalar::CAPACITY`. + let mut bytes: [u8; 32] = [0u8; 32]; + bytes[0..31].copy_from_slice(&lower_bytes); + // Add 0bXX000000 that leaves the first six bits untouched. + bytes[31] = n + (i << 6); + assert!( + bytes[31] > 63, + "The last byte expected to be grater than 63 to exceed CAPACITY" + ); + let over_capacity = ::scalar_from_bytes(bytes); + // Check that two topmost bits are ignored. + assert_eq!(fits_capacity, over_capacity); } } @@ -209,6 +305,7 @@ mod tests { let scalar_vec64 = scalar.into_repr(); let scalar_res = >::from_repr(&scalar_vec64); assert!(scalar_res.is_ok()); + assert_eq!(scalar_vec64.len(), 4); assert_eq!(scalar, scalar_res.unwrap()); } } @@ -263,9 +360,6 @@ mod tests { }; } - type G1 = ArkGroup; - type G2 = ArkGroup; - macro_test_scalar_byte_conversion!(sc_bytes_conv_g1, G1); macro_test_scalar_byte_conversion!(sc_bytes_conv_g2, G2); macro_test_scalar_byte_conversion!(sc_bytes_conv_bls12, Bls12); From 658aca4ac86a1a20c63833c6ddf9b1c977e97eeb Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 18 Jan 2024 13:42:40 +0100 Subject: [PATCH 52/53] Clarify behaviour of scalar_from_bytes for short and long input --- rust-src/concordium_base/src/curve_arithmetic/mod.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/mod.rs b/rust-src/concordium_base/src/curve_arithmetic/mod.rs index 5d3e7025b..9320ddc13 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/mod.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/mod.rs @@ -89,7 +89,7 @@ pub trait PrimeField: Field { /// How many bits of information can be reliably stored in the field /// element. It is expected that `num_limbs * 64 - CAPACITY < 64`, where /// `num_limbs` is the size of vector returned by - /// `PrimeField::into_repr(self)`. + /// [PrimeField::into_repr]. const CAPACITY: u32; /// Get a big integer representation with least significant digit first. @@ -154,8 +154,12 @@ pub trait Curve: /// Make a scalar from a 64-bit unsigned integer. This function assumes that /// the field is big enough to accommodate any 64-bit unsigned integer. fn scalar_from_u64(n: u64) -> Self::Scalar; - /// Make a scalar by taking the first Scalar::CAPACITY bits and interpreting - /// them as a little-endian integer. + /// Make a scalar by taking the first `Scalar::CAPACITY`` bits and + /// interpreting them as a little-endian integer. If the input length is + /// smaller than `num_limbs * 8` bytes then extra zeros are added in topmost + /// bytes. If the input lenght is greater, bytes after the first + /// `num_limbs * 8` are ignored. Where `num_limbs` is the size of vector + /// returned by [PrimeField::into_repr]. fn scalar_from_bytes>(bs: A) -> Self::Scalar; /// Hash to a curve point from a seed. This is deterministic function. fn hash_to_group(m: &[u8]) -> Result; From 0ef0868984a67400e20f7ff76cede95ac1597ce8 Mon Sep 17 00:00:00 2001 From: Danil Annenkov Date: Thu, 18 Jan 2024 15:19:40 +0100 Subject: [PATCH 53/53] Update rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs Co-authored-by: eb-concordium <77331975+eb-concordium@users.noreply.github.com> --- .../concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs index 4bfc88a16..165ce71b1 100644 --- a/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs +++ b/rust-src/concordium_base/src/curve_arithmetic/bls12_381_arkworks.rs @@ -285,7 +285,7 @@ mod tests { } } - /// Test that `into_repr()` correclty converts a scalar constructed from a + /// Test that `into_repr()` correctly converts a scalar constructed from a /// byte array to an array of limbs with least significant digits first. #[test] fn test_into() {