mirror of
https://github.com/serai-dex/serai.git
synced 2024-11-17 09:27:36 +00:00
79aff5d4c8
* Partial move to ff 0.13 It turns out the newly released k256 0.12 isn't on ff 0.13, preventing further work at this time. * Update all crates to work on ff 0.13 The provided curves still need to be expanded to fit the new API. * Finish adding dalek-ff-group ff 0.13 constants * Correct FieldElement::product definition Also stops exporting macros. * Test most new parts of ff 0.13 * Additionally test ff-group-tests with BLS12-381 and the pasta curves We only tested curves from RustCrypto. Now we test a curve offered by zk-crypto, the group behind ff/group, and the pasta curves, which is by Zcash (though Zcash developers are also behind zk-crypto). * Finish Ed448 Fully specifies all constants, passes all tests in ff-group-tests, and finishes moving to ff-0.13. * Add RustCrypto/elliptic-curves to allowed git repos Needed due to k256/p256 incorrectly defining product. * Finish writing ff 0.13 tests * Add additional comments to dalek * Further comments * Update ethereum-serai to ff 0.13
92 lines
2.7 KiB
Rust
92 lines
2.7 KiB
Rust
use k256::{
|
|
elliptic_curve::{bigint::ArrayEncoding, ops::Reduce, sec1::ToEncodedPoint},
|
|
ProjectivePoint, Scalar, U256,
|
|
};
|
|
use frost::{curve::Secp256k1, Participant};
|
|
|
|
use ethereum_serai::crypto::*;
|
|
|
|
#[test]
|
|
fn test_ecrecover() {
|
|
use rand_core::OsRng;
|
|
use sha2::Sha256;
|
|
use sha3::{Digest, Keccak256};
|
|
use k256::ecdsa::{hazmat::SignPrimitive, signature::DigestVerifier, SigningKey, VerifyingKey};
|
|
|
|
let private = SigningKey::random(&mut OsRng);
|
|
let public = VerifyingKey::from(&private);
|
|
|
|
const MESSAGE: &[u8] = b"Hello, World!";
|
|
let (sig, recovery_id) = private
|
|
.as_nonzero_scalar()
|
|
.try_sign_prehashed_rfc6979::<Sha256>(&Keccak256::digest(MESSAGE), b"")
|
|
.unwrap();
|
|
#[allow(clippy::unit_cmp)] // Intended to assert this wasn't changed to Result<bool>
|
|
{
|
|
assert_eq!(public.verify_digest(Keccak256::new_with_prefix(MESSAGE), &sig).unwrap(), ());
|
|
}
|
|
|
|
assert_eq!(
|
|
ecrecover(hash_to_scalar(MESSAGE), recovery_id.unwrap().is_y_odd().into(), *sig.r(), *sig.s())
|
|
.unwrap(),
|
|
address(&ProjectivePoint::from(public.as_affine()))
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_signing() {
|
|
use frost::{
|
|
algorithm::IetfSchnorr,
|
|
tests::{algorithm_machines, key_gen, sign},
|
|
};
|
|
use rand_core::OsRng;
|
|
|
|
let keys = key_gen::<_, Secp256k1>(&mut OsRng);
|
|
let _group_key = keys[&Participant::new(1).unwrap()].group_key();
|
|
|
|
const MESSAGE: &[u8] = b"Hello, World!";
|
|
|
|
let algo = IetfSchnorr::<Secp256k1, EthereumHram>::ietf();
|
|
let _sig = sign(
|
|
&mut OsRng,
|
|
algo,
|
|
keys.clone(),
|
|
algorithm_machines(&mut OsRng, IetfSchnorr::<Secp256k1, EthereumHram>::ietf(), &keys),
|
|
MESSAGE,
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_ecrecover_hack() {
|
|
use frost::{
|
|
algorithm::IetfSchnorr,
|
|
tests::{algorithm_machines, key_gen, sign},
|
|
};
|
|
use rand_core::OsRng;
|
|
|
|
let keys = key_gen::<_, Secp256k1>(&mut OsRng);
|
|
let group_key = keys[&Participant::new(1).unwrap()].group_key();
|
|
let group_key_encoded = group_key.to_encoded_point(true);
|
|
let group_key_compressed = group_key_encoded.as_ref();
|
|
let group_key_x = Scalar::reduce(U256::from_be_slice(&group_key_compressed[1 .. 33]));
|
|
|
|
const MESSAGE: &[u8] = b"Hello, World!";
|
|
let hashed_message = keccak256(MESSAGE);
|
|
let chain_id = U256::ONE;
|
|
|
|
let full_message = &[chain_id.to_be_byte_array().as_slice(), &hashed_message].concat();
|
|
|
|
let algo = IetfSchnorr::<Secp256k1, EthereumHram>::ietf();
|
|
let sig = sign(
|
|
&mut OsRng,
|
|
algo.clone(),
|
|
keys.clone(),
|
|
algorithm_machines(&mut OsRng, algo, &keys),
|
|
full_message,
|
|
);
|
|
|
|
let (sr, er) =
|
|
preprocess_signature_for_ecrecover(hashed_message, &sig.R, sig.s, &group_key, chain_id);
|
|
let q = ecrecover(sr, group_key_compressed[0] - 2, group_key_x, er).unwrap();
|
|
assert_eq!(q, address(&sig.R));
|
|
}
|