Merge branch 'feature/github-actions' into main

This commit is contained in:
Isis Lovecruft 2021-09-14 01:08:27 +00:00
commit ad461f4f0f
No known key found for this signature in database
GPG key ID: AB41313533E8E812
5 changed files with 208 additions and 4 deletions

131
.github/workflows/rust.yml vendored Normal file
View file

@ -0,0 +1,131 @@
name: Rust
on:
push:
branches: [ '*' ]
pull_request:
branches: [ main, develop ]
env:
CARGO_TERM_COLOR: always
jobs:
test-u32:
name: Test u32 backend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --no-default-features --features "std u32_backend"
test-u64:
name: Test u64 backend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --no-default-features --features "std u64_backend"
test-simd:
name: Test simd backend (nightly)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --no-default-features --features "std nightly simd_backend"
test-defaults-serde:
name: Test default feature selection and serde
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --features "serde"
test-alloc-u32:
name: Test no_std+alloc with u32 backend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --lib --no-default-features --features "alloc u32_backend"
test-batch-deterministic:
name: Test deterministic batch verification
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --features "batch_deterministic"
msrv:
name: Current MSRV is 1.41
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: 1.41
override: true
- uses: actions-rs/cargo@v1
with:
command: build
bench:
name: Check that benchmarks compile
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: bench
# This filter selects no benchmarks, so we don't run any, only build them.
args: --features "batch" "DONTRUNBENCHMARKS"

View file

@ -30,7 +30,7 @@ rand_core = { version = "0.5", default-features = false, optional = true }
serde_crate = { package = "serde", version = "1.0", default-features = false, optional = true }
serde_bytes = { version = "0.11", optional = true }
sha2 = { version = "0.9", default-features = false }
zeroize = { version = "1", default-features = false }
zeroize = { version = "~1.3", default-features = false }
[dev-dependencies]
hex = "^0.4"

View file

@ -124,7 +124,7 @@ However, if you require this, please see the documentation for the
`verify_strict()` function, which does the full checks for the group elements.
This functionality is available by default.
If for some reason—although we strongely advise you not to—you need to conform
If for some reason—although we strongly advise you not to—you need to conform
to the original specification of ed25519 signatures as in the excerpt from the
paper above, you can disable scalar malleability checking via
`--features='legacy_compatibility'`. **WE STRONGLY ADVISE AGAINST THIS.**

View file

@ -235,8 +235,7 @@
#![warn(future_incompatible)]
#![deny(missing_docs)] // refuse to compile if documentation is missing
#![cfg(not(test))]
#![forbid(unsafe_code)]
#![cfg_attr(not(test), forbid(unsafe_code))]
#[cfg(any(feature = "std", test))]
#[macro_use]

View file

@ -28,7 +28,10 @@ use sha2::Sha512;
#[cfg(test)]
mod vectors {
use curve25519_dalek::{edwards::EdwardsPoint, scalar::Scalar};
use ed25519::signature::Signature as _;
use sha2::{digest::Digest, Sha512};
use std::convert::TryFrom;
use std::io::BufReader;
use std::io::BufRead;
@ -112,6 +115,77 @@ mod vectors {
assert!(keypair.verify_prehashed(prehash_for_verifying, None, &sig2).is_ok(),
"Could not verify ed25519ph signature!");
}
// Taken from curve25519_dalek::constants::EIGHT_TORSION[4]
const EIGHT_TORSION_4: [u8; 32] = [
236, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127,
];
fn compute_hram(message: &[u8], pub_key: &EdwardsPoint, signature_r: &EdwardsPoint) -> Scalar {
let k_bytes = Sha512::default()
.chain(&signature_r.compress().as_bytes())
.chain(&pub_key.compress().as_bytes()[..])
.chain(&message);
let mut k_output = [0u8; 64];
k_output.copy_from_slice(k_bytes.finalize().as_slice());
Scalar::from_bytes_mod_order_wide(&k_output)
}
fn serialize_signature(r: &EdwardsPoint, s: &Scalar) -> Vec<u8> {
[&r.compress().as_bytes()[..], &s.as_bytes()[..]].concat()
}
#[test]
fn repudiation() {
use curve25519_dalek::traits::IsIdentity;
use std::ops::Neg;
let message1 = b"Send 100 USD to Alice";
let message2 = b"Send 100000 USD to Alice";
// Pick a random Scalar
fn non_null_scalar() -> Scalar {
let mut rng = rand::rngs::OsRng;
let mut s_candidate = Scalar::random(&mut rng);
while s_candidate == Scalar::zero() {
s_candidate = Scalar::random(&mut rng);
}
s_candidate
}
let mut s: Scalar = non_null_scalar();
fn pick_r_and_pubkey(s: Scalar) -> (EdwardsPoint, EdwardsPoint) {
let r0 = s * curve25519_dalek::constants::ED25519_BASEPOINT_POINT;
// Pick a torsion point of order 2
let pub_key = curve25519_dalek::edwards::CompressedEdwardsY(EIGHT_TORSION_4)
.decompress()
.unwrap();
let r = r0 + pub_key.neg();
(r, pub_key)
}
let (mut r, mut pub_key) = pick_r_and_pubkey(s);
while !(pub_key.neg() + compute_hram(message1, &pub_key, &r) * pub_key).is_identity()
|| !(pub_key.neg() + compute_hram(message2, &pub_key, &r) * pub_key).is_identity()
{
s = non_null_scalar();
let key = pick_r_and_pubkey(s);
r = key.0;
pub_key = key.1;
}
let signature = serialize_signature(&r, &s);
let pk = PublicKey::from_bytes(&pub_key.compress().as_bytes()[..]).unwrap();
let sig = Signature::try_from(&signature[..]).unwrap();
// The same signature verifies for both messages
assert!(pk.verify(message1, &sig).is_ok() && pk.verify(message2, &sig).is_ok());
// But not with a strict signature: verify_strict refuses small order keys
assert!(
pk.verify_strict(message1, &sig).is_err() || pk.verify_strict(message2, &sig).is_err()
);
}
}
#[cfg(test)]