From abcc9076667db9642fddc119ba89784137a01357 Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Sun, 10 Nov 2024 22:04:26 +0300 Subject: [PATCH 1/5] feat(frost-ed448): add no_std support --- .github/workflows/main.yml | 3 +-- frost-ed448/Cargo.toml | 2 +- frost-ed448/src/lib.rs | 31 ++++++++++++++-------------- frost-ed448/src/tests/deserialize.rs | 8 +++---- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1ac32783..0feca6b8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -66,10 +66,9 @@ jobs: build_no_std: name: build with no_std runs-on: ubuntu-latest - # Skip ed448 which does not support it. strategy: matrix: - crate: [ristretto255, ed25519, p256, secp256k1, rerandomized] + crate: [ed448, ristretto255, ed25519, p256, secp256k1, rerandomized] steps: - uses: actions/checkout@v4.1.7 - uses: dtolnay/rust-toolchain@master diff --git a/frost-ed448/Cargo.toml b/frost-ed448/Cargo.toml index 17ba4b5f..07945a00 100644 --- a/frost-ed448/Cargo.toml +++ b/frost-ed448/Cargo.toml @@ -23,7 +23,7 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] document-features = "0.2.7" -ed448-goldilocks = { version = "0.9.0" } +ed448-goldilocks-plus = { version = "0.13.0", features = ["alloc"], default-features = false } frost-core = { path = "../frost-core", version = "2.0.0", default-features = false } frost-rerandomized = { path = "../frost-rerandomized", version = "2.0.0", default-features = false } rand_core = "0.6" diff --git a/frost-ed448/src/lib.rs b/frost-ed448/src/lib.rs index 4ceb707e..8efc6828 100644 --- a/frost-ed448/src/lib.rs +++ b/frost-ed448/src/lib.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(non_snake_case)] #![deny(missing_docs)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] @@ -9,9 +10,8 @@ extern crate alloc; use std::collections::BTreeMap; -use ed448_goldilocks::{ - curve::{edwards::CompressedEdwardsY, ExtendedPoint}, - Scalar, +use ed448_goldilocks_plus::{ + CompressedEdwardsY, EdwardsPoint, Scalar, ScalarBytes, WideScalarBytes, }; use frost_rerandomized::RandomizedCiphersuite; use rand_core::{CryptoRng, RngCore}; @@ -44,11 +44,11 @@ impl Field for Ed448ScalarField { type Serialization = [u8; 57]; fn zero() -> Self::Scalar { - Scalar::zero() + Scalar::ZERO } fn one() -> Self::Scalar { - Scalar::one() + Scalar::ONE } fn invert(scalar: &Self::Scalar) -> Result { @@ -64,11 +64,11 @@ impl Field for Ed448ScalarField { } fn serialize(scalar: &Self::Scalar) -> Self::Serialization { - scalar.to_bytes_rfc_8032() + scalar.to_bytes_rfc_8032().into() } fn deserialize(buf: &Self::Serialization) -> Result { - match Scalar::from_canonical_bytes(*buf) { + match Scalar::from_canonical_bytes(ScalarBytes::from_slice(buf)).into() { Some(s) => Ok(s), None => Err(FieldError::MalformedScalar), } @@ -86,20 +86,20 @@ pub struct Ed448Group; impl Group for Ed448Group { type Field = Ed448ScalarField; - type Element = ExtendedPoint; + type Element = EdwardsPoint; type Serialization = [u8; 57]; fn cofactor() -> ::Scalar { - Scalar::one() + Scalar::ONE } fn identity() -> Self::Element { - Self::Element::identity() + Self::Element::IDENTITY } fn generator() -> Self::Element { - Self::Element::generator() + Self::Element::GENERATOR } fn serialize(element: &Self::Element) -> Result { @@ -111,11 +111,11 @@ impl Group for Ed448Group { fn deserialize(buf: &Self::Serialization) -> Result { let compressed = CompressedEdwardsY(*buf); - match compressed.decompress() { + match compressed.decompress().into_option() { Some(point) => { if point == Self::identity() { Err(GroupError::InvalidIdentityElement) - } else if point.is_torsion_free() { + } else if point.is_torsion_free().into() { // decompress() does not check for canonicality, so we // check by recompressing and comparing if point.compress().0 != compressed.0 { @@ -144,8 +144,9 @@ fn hash_to_array(inputs: &[&[u8]]) -> [u8; 114] { } fn hash_to_scalar(inputs: &[&[u8]]) -> Scalar { - let output = hash_to_array(inputs); - Scalar::from_bytes_mod_order_wide(&output) + let temp = hash_to_array(inputs); + let output = WideScalarBytes::from_slice(&temp); + Scalar::from_bytes_mod_order_wide(output) } /// Context string from the ciphersuite in the [spec] diff --git a/frost-ed448/src/tests/deserialize.rs b/frost-ed448/src/tests/deserialize.rs index 6c86b77f..f9698c98 100644 --- a/frost-ed448/src/tests/deserialize.rs +++ b/frost-ed448/src/tests/deserialize.rs @@ -1,10 +1,10 @@ use crate::*; -use ed448_goldilocks::curve::ExtendedPoint; +use ed448_goldilocks_plus::EdwardsPoint; use frost_core::Ciphersuite; #[test] fn check_deserialize_non_canonical() { - let mut encoded_generator = ExtendedPoint::generator().compress().0; + let mut encoded_generator = EdwardsPoint::GENERATOR.compress().0; let r = ::Group::deserialize(&encoded_generator); assert!(r.is_ok()); @@ -30,12 +30,12 @@ fn check_deserialize_non_prime_order() { .try_into() .unwrap(); let r = ::Group::deserialize(&encoded_point); - assert_eq!(r, Err(GroupError::InvalidNonPrimeOrderElement)); + assert_eq!(r, Err(GroupError::MalformedElement)); // TODO: it should be `GroupError::NonPrimeOrderElement` } #[test] fn check_deserialize_identity() { - let encoded_identity = ExtendedPoint::identity().compress().0; + let encoded_identity = EdwardsPoint::IDENTITY.compress().0; let r = ::Group::deserialize(&encoded_identity); assert_eq!(r, Err(GroupError::InvalidIdentityElement)); From eaa2e646add00cc05c0acb93b188fd5f0e0ac42f Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Sun, 10 Nov 2024 22:10:32 +0300 Subject: [PATCH 2/5] update changelog --- frost-core/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frost-core/CHANGELOG.md b/frost-core/CHANGELOG.md index 4057939c..3ebbc30e 100644 --- a/frost-core/CHANGELOG.md +++ b/frost-core/CHANGELOG.md @@ -7,6 +7,8 @@ Entries are listed in reverse chronological order. * It is now possible to identify the culprit in `frost_core::keys::dkg::part3()` if an invalid secret share was sent by one of the participants (by calling frost_core::Error::culprit()`). +* Added no-std support for frost-ed448 crate. This became possible after migration to `ed448-goldilocks-plus` (fork of + `ed448-goldilocks`). ## 2.0.0 From 497b38ce4c8e500b80a29ea7ff8b77fc9e86d01d Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Sun, 10 Nov 2024 23:49:00 +0300 Subject: [PATCH 3/5] use git dependency for demo --- frost-ed448/Cargo.toml | 3 ++- frost-ed448/src/lib.rs | 2 +- frost-ed448/src/tests/deserialize.rs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frost-ed448/Cargo.toml b/frost-ed448/Cargo.toml index 07945a00..b6afee43 100644 --- a/frost-ed448/Cargo.toml +++ b/frost-ed448/Cargo.toml @@ -23,7 +23,8 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] document-features = "0.2.7" -ed448-goldilocks-plus = { version = "0.13.0", features = ["alloc"], default-features = false } +# TODO: remove git dependency once https://github.com/mikelodder7/Ed448-Goldilocks/pull/2 is merged +ed448-goldilocks-plus = { git = "https://github.com/StackOverflowExcept1on/Ed448-Goldilocks", branch = "decompress-unchecked", version = "0.13.1", features = ["alloc"], default-features = false } frost-core = { path = "../frost-core", version = "2.0.0", default-features = false } frost-rerandomized = { path = "../frost-rerandomized", version = "2.0.0", default-features = false } rand_core = "0.6" diff --git a/frost-ed448/src/lib.rs b/frost-ed448/src/lib.rs index 8efc6828..687006d3 100644 --- a/frost-ed448/src/lib.rs +++ b/frost-ed448/src/lib.rs @@ -111,7 +111,7 @@ impl Group for Ed448Group { fn deserialize(buf: &Self::Serialization) -> Result { let compressed = CompressedEdwardsY(*buf); - match compressed.decompress().into_option() { + match compressed.decompress_unchecked().into_option() { Some(point) => { if point == Self::identity() { Err(GroupError::InvalidIdentityElement) diff --git a/frost-ed448/src/tests/deserialize.rs b/frost-ed448/src/tests/deserialize.rs index f9698c98..e887334f 100644 --- a/frost-ed448/src/tests/deserialize.rs +++ b/frost-ed448/src/tests/deserialize.rs @@ -30,7 +30,7 @@ fn check_deserialize_non_prime_order() { .try_into() .unwrap(); let r = ::Group::deserialize(&encoded_point); - assert_eq!(r, Err(GroupError::MalformedElement)); // TODO: it should be `GroupError::NonPrimeOrderElement` + assert_eq!(r, Err(GroupError::InvalidNonPrimeOrderElement)); } #[test] From 4f83b20c4fe4fa2956523d657d850cc08722e15f Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Mon, 11 Nov 2024 04:06:00 +0300 Subject: [PATCH 4/5] remove git dependency --- frost-ed448/Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frost-ed448/Cargo.toml b/frost-ed448/Cargo.toml index b6afee43..1fd1e02b 100644 --- a/frost-ed448/Cargo.toml +++ b/frost-ed448/Cargo.toml @@ -23,8 +23,7 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] document-features = "0.2.7" -# TODO: remove git dependency once https://github.com/mikelodder7/Ed448-Goldilocks/pull/2 is merged -ed448-goldilocks-plus = { git = "https://github.com/StackOverflowExcept1on/Ed448-Goldilocks", branch = "decompress-unchecked", version = "0.13.1", features = ["alloc"], default-features = false } +ed448-goldilocks-plus = { version = "0.13.1", features = ["alloc"], default-features = false } frost-core = { path = "../frost-core", version = "2.0.0", default-features = false } frost-rerandomized = { path = "../frost-rerandomized", version = "2.0.0", default-features = false } rand_core = "0.6" From 89e8648334850e5a07b01893621d74c2946b329b Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:38:22 +0300 Subject: [PATCH 5/5] replace std with alloc in frost-ed448 --- frost-ed448/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frost-ed448/src/lib.rs b/frost-ed448/src/lib.rs index 687006d3..237dbb9f 100644 --- a/frost-ed448/src/lib.rs +++ b/frost-ed448/src/lib.rs @@ -8,7 +8,7 @@ extern crate alloc; -use std::collections::BTreeMap; +use alloc::collections::BTreeMap; use ed448_goldilocks_plus::{ CompressedEdwardsY, EdwardsPoint, Scalar, ScalarBytes, WideScalarBytes, @@ -231,7 +231,6 @@ pub type Identifier = frost::Identifier; /// FROST(Ed448, SHAKE256) keys, key generation, key shares. pub mod keys { use super::*; - use std::collections::BTreeMap; /// The identifier list to use when generating key shares. pub type IdentifierList<'a> = frost::keys::IdentifierList<'a, E>;