Skip to content

Commit

Permalink
Merge pull request liangping#3 from keithsue/sufay/merge-upstream
Browse files Browse the repository at this point in the history
Merge upstream
  • Loading branch information
liangping authored Aug 14, 2024
2 parents 17c3886 + 97e3c98 commit ab3251b
Show file tree
Hide file tree
Showing 95 changed files with 1,957 additions and 578 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ jobs:
run: cargo llvm-cov report --lcov --ignore-filename-regex '.*(tests).*|benches.rs|gencode|helpers.rs' --output-path lcov.info

- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v3.1.4
uses: codecov/codecov-action@v4.0.1
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ jobs:
continue-on-error: true
steps:
- uses: actions/[email protected]
- uses: reviewdog/action-actionlint@v1.39.1
- uses: reviewdog/action-actionlint@v1.41.0
with:
level: warning
fail_on_error: false
2 changes: 1 addition & 1 deletion .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
# Drafts your next Release notes as Pull Requests are merged into main
- uses: release-drafter/release-drafter@v5
- uses: release-drafter/release-drafter@v6
with:
# (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml
config-name: release-drafter.yml
Expand Down
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,33 @@ Refer to the [ZF FROST book](https://frost.zfnd.org/).
## Status ⚠

The FROST specification is not yet finalized, though no significant changes are
expected at this point. This code base has been audited by NCC. The APIs and
types in `frost-core` are subject to change during the release candidate phase,
and will follow SemVer guarantees after 1.0.0.
expected at this point. This code base has been partially audited by NCC, see
below for details. The APIs and types in the crates contained in this repository
follow SemVer guarantees.

### NCC Audit

NCC performed [an
audit](https://research.nccgroup.com/2023/10/23/public-report-zcash-frost-security-assessment/)
of the v0.6.0 release (corresponding to commit 5fa17ed) of the following crates:

- frost-core
- frost-ed25519
- frost-ed448
- frost-p256
- frost-secp256k1
- frost-ristretto255

This includes key generation (both trusted dealer and DKG) and FROST signing.
This does not include rerandomized FROST.

The parts of the
[`Ed448-Goldilocks`](https://github.com/crate-crypto/Ed448-Goldilocks)
dependency that are used by `frost-ed448` were also in scope, namely the
elliptic curve operations.

All issues identified in the audit were addressed by us and reviewed by NCC.


## Usage

Expand Down
2 changes: 1 addition & 1 deletion book/src/tutorial/importing.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Add to your `Cargo.toml` file:

```
[dependencies]
frost-ristretto255 = "1.0.0-rc.0"
frost-ristretto255 = "1.0.0"
```

## Handling errors
Expand Down
36 changes: 27 additions & 9 deletions book/src/zcash/ywallet-demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
This tutorial explaing how to run the FROST demo using Ywallet that was
[presented during Zcon4](https://www.youtube.com/watch?v=xvzESdDtczo).

## Information

1. The Trusted Dealer journey
2. RedPallas
3. YWallet
4. Sprout
5. [Sapling](https://docs.rs/reddsa/0.5.1/reddsa/sapling/index.html)
6. [frost-ed25519 crate](https://crates.io/crates/frost-ed25519)

Ywallet supports [offline
signing](https://ywallet.app/advanced/offline_signature/), which allows having a
view-only account that can generate a transaction plan, which can be signed by
Expand All @@ -20,10 +29,23 @@ Install `cargo` and `git`.
Clone the repositories:

```
git clone --branch add-redpallas https://github.com/ZcashFoundation/frost-zcash-demo.git
git clone --branch frost-demo https://github.com/ZcashFoundation/zwallet.git
git clone https://github.com/ZcashFoundation/frost-zcash-demo.git
git clone --recurse-submodules --branch frost-demo https://github.com/ZcashFoundation/zwallet.git
git clone https://github.com/ZcashFoundation/zcash.git
```

Download Sprout and Sapling parameters:


[Sprout params](https://download.z.cash/downloads/sprout-groth16.params)

[Sapling spend params](https://download.z.cash/downloads/sapling-spend.params)

[Sapling output params](https://download.z.cash/downloads/sapling-output.params)

Move the params files into `zwallet/native/zcash-params/src/`


## Generating FROST key shares

First we will generate the FROST key shares. For simplicity we'll use trusted
Expand Down Expand Up @@ -79,7 +101,7 @@ We can finally generate a new wallet. Run the following command; it will
take a bit to compile. It will show a bunch of warnings which is normal.

```
cargo build --release --bin sign --features dotenv -- -g
cargo run --release --bin sign --features dotenv -- -g
```

When prompted for the `ak`, paste the `verifying_key` value that was printed in
Expand Down Expand Up @@ -120,11 +142,7 @@ funds become spendable (this may take ~10 minutes). You can check if the funds
are spendable by clicking the arrow button and checking "Spendable Balance"

```admonish warning
The address being show by Ywallet is an unified address that includes both
an Orchard and Sapling address. For the demo to work, you need to receive funds
in you Orchard address. Whether that will happens depend on multiple factors
so it's probably easier to just use the Orchard-only address printed by the
signer.
The address being show by Ywallet is a unified address that includes both an Orchard and Sapling address. For the demo to work, you need to receive funds in you Orchard address. Whether that will happen depends on multiple factors so it's probably easier to use just the Orchard-only address printed by the signer.
```

## Creating the transaction
Expand Down Expand Up @@ -165,7 +183,7 @@ cargo run --bin coordinator --features redpallas
And then:

- Paste the JSON public key package generate during key generation (it's a single
line with a JSON object.
line with a JSON object).
- Type `2` for the number of participants.
- Paste the identifier of the first participant, you can see it in the Secret
Share printed during key generation. If you used trusted dealer key
Expand Down
12 changes: 11 additions & 1 deletion frost-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@ Entries are listed in reverse chronological order.

## Unreleased


## Released

## 1.0.0

* Exposed the `SigningKey::from_scalar()` and `to_scalar()` methods. This
helps interoperability with other implementations.
* Exposed the `SigningNonces::from_nonces()` method to allow it to be
deserialized.
* Fixed bug that prevented deserialization with in some cases (e.g. JSON
containing escape codes).
* Added `new()` methods for `VerifirableSecretSharingCommitment` and
`CoefficientCommitment`.

## 1.0.0-rc.0

* The `frost-core::frost` module contents were merged into `frost-core`, thus
Expand Down
2 changes: 1 addition & 1 deletion frost-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ edition = "2021"
# When releasing to crates.io:
# - Update CHANGELOG.md
# - Create git tag.
version = "1.0.0-rc.0"
version = "1.0.0"
authors = [
"Deirdre Connolly <[email protected]>",
"Chelsea Komlo <[email protected]>",
Expand Down
24 changes: 14 additions & 10 deletions frost-core/src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::{scalar_mul::VartimeMultiscalarMul, Ciphersuite, Element, *};
pub struct Item<C: Ciphersuite> {
vk: VerifyingKey<C>,
sig: Signature<C>,
sig_params: C::SigningParameters,
c: Challenge<C>,
}

Expand All @@ -32,9 +33,15 @@ where
{
fn from((vk, sig, msg): (VerifyingKey<C>, Signature<C>, &'msg M)) -> Self {
// Compute c now to avoid dependency on the msg lifetime.
let c = <C>::challenge(&sig.R, &vk, msg.as_ref());

Self { vk, sig, c }
let sig_target = SigningTarget::from_message(msg);
let c = <C>::challenge(&sig.R, &vk, &sig_target);

Self {
vk,
sig,
sig_params: sig_target.sig_params,
c,
}
}
}

Expand All @@ -50,7 +57,8 @@ where
/// requires borrowing the message data, the `Item` type is unlinked
/// from the lifetime of the message.
pub fn verify_single(self) -> Result<(), Error<C>> {
self.vk.verify_prehashed(self.c, &self.sig)
self.vk
.verify_prehashed(self.c, &self.sig, &self.sig_params)
}
}

Expand Down Expand Up @@ -118,12 +126,8 @@ where

for item in self.signatures.iter() {
let z = item.sig.z;
let mut R = item.sig.R;
let mut vk = item.vk.element;
if <C>::is_need_tweaking() {
R = <C>::tweaked_R(&item.sig.R);
vk = <C>::tweaked_public_key(&item.vk.element);
}
let R = item.sig.R;
let vk = <C>::effective_pubkey_element(&item.vk, &item.sig_params);

let blind = <<C::Group as Group>::Field>::random(&mut rng);

Expand Down
6 changes: 3 additions & 3 deletions frost-core/src/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub(crate) fn sum_commitments<C: Ciphersuite>(
let mut group_commitment = vec![
CoefficientCommitment(<C::Group>::identity());
commitments
.get(0)
.first()
.ok_or(Error::IncorrectNumberOfCommitments)?
.0
.len()
Expand Down Expand Up @@ -412,7 +412,7 @@ where
/// element in the vector), or an error if the vector is empty.
pub(crate) fn verifying_key(&self) -> Result<VerifyingKey<C>, Error<C>> {
Ok(VerifyingKey::new(
self.0.get(0).ok_or(Error::MissingCommitment)?.0,
self.0.first().ok_or(Error::MissingCommitment)?.0,
))
}

Expand Down Expand Up @@ -619,7 +619,7 @@ fn evaluate_polynomial<C: Ciphersuite>(
}
value = value
+ *coefficients
.get(0)
.first()
.expect("coefficients must have at least one element");
value
}
Expand Down
42 changes: 31 additions & 11 deletions frost-core/src/keys/dkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use rand_core::{CryptoRng, RngCore};

use crate::{
Challenge, Ciphersuite, Element, Error, Field, Group, Header, Identifier, Scalar, Signature,
SigningKey, VerifyingKey,
SigningKey,
};

use super::{
Expand Down Expand Up @@ -289,6 +289,7 @@ pub fn part1<C: Ciphersuite, R: RngCore + CryptoRng>(
// > Every participant P_i computes a public commitment
// > C⃗_i = 〈φ_{i0}, ..., φ_{i(t−1)}〉, where φ_{ij} = g^{a_{ij}}, 0 ≤ j ≤ t − 1
let coefficients = generate_coefficients::<C, R>(min_signers as usize - 1, &mut rng);

let (coefficients, commitment) =
generate_secret_polynomial(&secret, max_signers, min_signers, coefficients)?;
let proof_of_knowledge =
Expand All @@ -313,7 +314,7 @@ pub fn part1<C: Ciphersuite, R: RngCore + CryptoRng>(
/// Generates the challenge for the proof of knowledge to a secret for the DKG.
fn challenge<C>(
identifier: Identifier<C>,
verifying_key: &VerifyingKey<C>,
verifying_key: &Element<C>,
R: &Element<C>,
) -> Option<Challenge<C>>
where
Expand All @@ -322,7 +323,7 @@ where
let mut preimage = vec![];

preimage.extend_from_slice(identifier.serialize().as_ref());
preimage.extend_from_slice(<C::Group>::serialize(&verifying_key.element).as_ref());
preimage.extend_from_slice(<C::Group>::serialize(&verifying_key).as_ref());
preimage.extend_from_slice(<C::Group>::serialize(R).as_ref());

Some(Challenge(C::HDKG(&preimage[..])?))
Expand All @@ -343,14 +344,23 @@ pub(crate) fn compute_proof_of_knowledge<C: Ciphersuite, R: RngCore + CryptoRng>
// > a_{i0} by calculating σ_i = (R_i, μ_i), such that k ← Z_q, R_i = g^k,
// > c_i = H(i, Φ, g^{a_{i0}} , R_i), μ_i = k + a_{i0} · c_i, with Φ being
// > a context string to prevent replay attacks.
let k = <<C::Group as Group>::Field>::random(&mut rng);
let R_i = <C::Group>::generator() * k;
let c_i = challenge::<C>(identifier, &commitment.verifying_key()?, &R_i)
.ok_or(Error::DKGNotSupported)?;
let mut k = <<C::Group as Group>::Field>::random(&mut rng);
let mut R_i = <C::Group>::generator() * k;
k = <C>::effective_nonce_secret(k, &R_i);
R_i = <C>::effective_nonce_element(R_i);

let verifying_key = commitment.verifying_key()?;
let sig_params = Default::default();

let phi_ell0 = <C>::effective_pubkey_element(&verifying_key, &sig_params);

let c_i = challenge::<C>(identifier, &phi_ell0, &R_i).ok_or(Error::DKGNotSupported)?;
let a_i0 = *coefficients
.get(0)
.first()
.expect("coefficients must have at least one element");
let mu_i = k + a_i0 * c_i.0;
let a_i0_effective = <C>::effective_secret_key(a_i0, &verifying_key, &sig_params);

let mu_i = k + a_i0_effective * c_i.0;
Ok(Signature { R: R_i, z: mu_i })
}

Expand All @@ -370,9 +380,12 @@ pub(crate) fn verify_proof_of_knowledge<C: Ciphersuite>(
let ell = identifier;
let R_ell = proof_of_knowledge.R;
let mu_ell = proof_of_knowledge.z;
let phi_ell0 = commitment.verifying_key()?;

let verifying_key = commitment.verifying_key()?;
let phi_ell0 = <C>::effective_pubkey_element(&verifying_key, &Default::default());
let c_ell = challenge::<C>(ell, &phi_ell0, &R_ell).ok_or(Error::DKGNotSupported)?;
if R_ell != <C::Group>::generator() * mu_ell - phi_ell0.element * c_ell.0 {

if R_ell != <C::Group>::generator() * mu_ell - phi_ell0 * c_ell.0 {
return Err(Error::InvalidProofOfKnowledge { culprit: ell });
}
Ok(())
Expand Down Expand Up @@ -405,6 +418,12 @@ pub fn part2<C: Ciphersuite>(
return Err(Error::IncorrectNumberOfPackages);
}

for package in round1_packages.values() {
if package.commitment.0.len() != secret_package.min_signers as usize {
return Err(Error::IncorrectNumberOfCommitments);
}
}

let mut round2_packages = BTreeMap::new();

for (sender_identifier, round1_package) in round1_packages {
Expand Down Expand Up @@ -517,6 +536,7 @@ pub fn part3<C: Ciphersuite>(

signing_share = signing_share + round2_secret_package.secret_share;
let signing_share = SigningShare(signing_share);

// Round 2, Step 4
//
// > Each P_i calculates their public verification share Y_i = g^{s_i}.
Expand Down
Loading

0 comments on commit ab3251b

Please sign in to comment.