mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 04:39:24 +00:00
Expand tests for ethereum-schnorr-contract
This commit is contained in:
@@ -12,7 +12,7 @@ use k256::{
|
||||
|
||||
use alloy_core::primitives::Address;
|
||||
|
||||
use crate::{PublicKey, Signature};
|
||||
use crate::{Signature, tests::test_key};
|
||||
|
||||
// The ecrecover opcode, yet with if the y is odd replacing v
|
||||
fn ecrecover(message: Scalar, odd_y: bool, r: Scalar, s: Scalar) -> Option<[u8; 20]> {
|
||||
@@ -64,12 +64,7 @@ fn test_ecrecover() {
|
||||
// of efficiently verifying Schnorr signatures in an Ethereum contract
|
||||
#[test]
|
||||
fn nonce_recovery_via_ecrecover() {
|
||||
let (key, public_key) = loop {
|
||||
let key = Scalar::random(&mut OsRng);
|
||||
if let Some(public_key) = PublicKey::new(ProjectivePoint::GENERATOR * key) {
|
||||
break (key, public_key);
|
||||
}
|
||||
};
|
||||
let (key, public_key) = test_key();
|
||||
|
||||
let nonce = Scalar::random(&mut OsRng);
|
||||
let R = ProjectivePoint::GENERATOR * nonce;
|
||||
@@ -81,26 +76,28 @@ fn nonce_recovery_via_ecrecover() {
|
||||
let s = nonce + (c * key);
|
||||
|
||||
/*
|
||||
An ECDSA signature is `(r, s)` with `s = (H(m) + rx) / k`, where:
|
||||
- `m` is the message
|
||||
An ECDSA signature is `(r, s)` with `s = (m + (r * x)) / k`, where:
|
||||
- `m` is the hash of the message
|
||||
- `r` is the x-coordinate of the nonce, reduced into a scalar
|
||||
- `x` is the private key
|
||||
- `k` is the nonce
|
||||
|
||||
We fix the recovery ID to be for the even key with an x-coordinate < the order. Accordingly,
|
||||
`kG = Point::from(Even, r)`. This enables recovering the public key via
|
||||
`((s Point::from(Even, r)) - H(m)G) / r`.
|
||||
`k * G = Point::from(Even, r)`. This enables recovering the public key via
|
||||
`((s * Point::from(Even, r)) - (m * G)) / r`.
|
||||
|
||||
We want to calculate `R` from `(c, s)` where `s = r + cx`. That means we need to calculate
|
||||
`sG - cX`.
|
||||
`(s * G) - (c * X)`.
|
||||
|
||||
We can calculate `sG - cX` with `((s Point::from(Even, r)) - H(m)G) / r` if:
|
||||
- Latter `r` = `X.x`
|
||||
- Latter `s` = `c`
|
||||
- `H(m)` = former `s`
|
||||
This gets us to `(cX - sG) / X.x`. If we additionally scale the latter's `s, H(m)` values (the
|
||||
former's `c, s` values) by `X.x`, we get `cX - sG`. This just requires negating each to achieve
|
||||
`sG - cX`.
|
||||
We can calculate `(s * G) - (c * X)` with `((s * Point::from(Even, r)) - (m * G)) / r` if:
|
||||
- ECDSA `r` = `X.x`, the x-coordinate of the Schnorr public key
|
||||
- ECDSA `s` = `c`, the Schnorr signature's challenge
|
||||
- ECDSA `m` = Schnorr `s`
|
||||
This gets us to `((c * X) - (s * G)) / X.x`. If we additionally scale the ECDSA `s, m` values
|
||||
(the Schnorr `c, s` values) by `X.x`, we get `(c * X) - (s * G)`. This just requires negating
|
||||
to achieve `(s * G) - (c * X)`.
|
||||
|
||||
With `R`, we can recalculate and compare the challenges to confirm the signature is valid.
|
||||
*/
|
||||
let x_scalar = <Scalar as Reduce<U256>>::reduce_bytes(&public_key.point().to_affine().x());
|
||||
let sa = -(s * x_scalar);
|
||||
|
||||
Reference in New Issue
Block a user