Skip to content

Commit a32ae3f

Browse files
authored
Don't reject small-order verification keys (#137)
* Don't reject small-order verification keys Fixes #127. * Added missing changelog entries
1 parent 2f240d8 commit a32ae3f

File tree

3 files changed

+46
-8
lines changed

3 files changed

+46
-8
lines changed

CHANGELOG.md

+28
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,34 @@
22

33
Entries are listed in reverse chronological order.
44

5+
## Unreleased
6+
7+
* Fixed a bug where small-order verification keys (including the identity) were
8+
handled inconsistently: the `VerificationKey` parsing logic rejected them, but
9+
the identity `VerificationKey` could be produced from the zero `SigningKey`.
10+
The behaviour is now to consistently accept all small-order verification keys,
11+
matching the RedDSA specification.
12+
13+
* Downstream users who currently rely on the inconsistent behaviour (for e.g.
14+
consensus compatibility, either explicitly wanting to reject small-order
15+
verification keys, or on the belief that this crate implemented the RedDSA
16+
specification) should continue to use previous versions of this crate, until
17+
they can either move the checks into their own code, or migrate their
18+
consensus rules to match the RedDSA specification.
19+
20+
## 0.4.0
21+
22+
* Upgrade `rand` to 0.8, `rand_core` to 0.6, and `rand_chacha` to 0.3, together
23+
(#55)
24+
* Migrate to `jubjub 0.6` (#59)
25+
* Derive `Debug, PartialEq` (#67)
26+
* Restrict the maximum number of FROST participants to 255 by using `u8` (#66)
27+
28+
## 0.3.0
29+
30+
* Initial support for FROST (Flexible Round-Optimized Schnorr Threshold)
31+
signatures.
32+
533
## 0.2.2
634

735
* Make `batch::Item: Clone + Debug` and add `batch::Item::verify_single`

src/verification_key.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,13 @@ impl<T: SigType> TryFrom<VerificationKeyBytes<T>> for VerificationKey<T> {
9999
let maybe_point = jubjub::AffinePoint::from_bytes(bytes.bytes);
100100
if maybe_point.is_some().into() {
101101
let point: jubjub::ExtendedPoint = maybe_point.unwrap().into();
102-
// This checks that the verification key is not of small order.
103-
if <bool>::from(point.is_small_order()) == false {
104-
Ok(VerificationKey { point, bytes })
105-
} else {
106-
Err(Error::MalformedVerificationKey)
107-
}
102+
// Note that small-order verification keys (including the identity) are not
103+
// rejected here. Previously they were rejected, but this was a bug as the
104+
// RedDSA specification allows them. Zcash Sapling rejects small-order points
105+
// for the RedJubjub spend authorization key rk; this now occurs separately.
106+
// Meanwhile, Zcash Orchard uses a prime-order group, so the only small-order
107+
// point would be the identity, which is allowed in Orchard.
108+
Ok(VerificationKey { point, bytes })
108109
} else {
109110
Err(Error::MalformedVerificationKey)
110111
}

tests/smallorder.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,20 @@ use jubjub::{AffinePoint, Fq};
55
use redjubjub::*;
66

77
#[test]
8-
fn smallorder_publickey_fails() {
8+
fn identity_publickey_passes() {
9+
let identity = AffinePoint::identity();
10+
assert_eq!(<bool>::from(identity.is_small_order()), true);
11+
let bytes = identity.to_bytes();
12+
let pk_bytes = VerificationKeyBytes::<SpendAuth>::from(bytes);
13+
assert!(VerificationKey::<SpendAuth>::try_from(pk_bytes).is_ok());
14+
}
15+
16+
#[test]
17+
fn smallorder_publickey_passes() {
918
// (1,0) is a point of order 4 on any Edwards curve
1019
let order4 = AffinePoint::from_raw_unchecked(Fq::one(), Fq::zero());
1120
assert_eq!(<bool>::from(order4.is_small_order()), true);
1221
let bytes = order4.to_bytes();
1322
let pk_bytes = VerificationKeyBytes::<SpendAuth>::from(bytes);
14-
assert!(VerificationKey::<SpendAuth>::try_from(pk_bytes).is_err());
23+
assert!(VerificationKey::<SpendAuth>::try_from(pk_bytes).is_ok());
1524
}

0 commit comments

Comments
 (0)