Implement recovery of DSA x
This commit is contained in:
11
src/dsa.rs
11
src/dsa.rs
@@ -22,6 +22,7 @@ pub struct DsaKeys {
|
|||||||
pub struct DsaSig {
|
pub struct DsaSig {
|
||||||
pub r: BigNum,
|
pub r: BigNum,
|
||||||
pub s: BigNum,
|
pub s: BigNum,
|
||||||
|
pub k: BigNum,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DsaParameters {
|
impl DsaParameters {
|
||||||
@@ -65,7 +66,7 @@ impl DsaKeys {
|
|||||||
// In the unlikely case that s=0, crash.
|
// In the unlikely case that s=0, crash.
|
||||||
assert!(s != zero, "s is zero");
|
assert!(s != zero, "s is zero");
|
||||||
|
|
||||||
Ok(DsaSig { r, s })
|
Ok(DsaSig { r, s, k })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify(
|
pub fn verify(
|
||||||
@@ -99,6 +100,14 @@ impl DsaKeys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn recover_x(params: &DsaParameters, msg: &Bytes, sig: &DsaSig) -> Result<BigNum, ErrorStack> {
|
||||||
|
// (s * k) - H(msg)
|
||||||
|
// x = ---------------- mod q
|
||||||
|
// r
|
||||||
|
let x = &(&rsa::invmod(&sig.r, ¶ms.q)? * &(&(&sig.s * &sig.k) - &h(msg)?)) % ¶ms.q;
|
||||||
|
Ok(x)
|
||||||
|
}
|
||||||
|
|
||||||
fn h(message: &Bytes) -> Result<BigNum, ErrorStack> {
|
fn h(message: &Bytes) -> Result<BigNum, ErrorStack> {
|
||||||
let mut s1 = sha1::Sha1::default();
|
let mut s1 = sha1::Sha1::default();
|
||||||
BigNum::from_slice(&(s1.hash(message).0))
|
BigNum::from_slice(&(s1.hash(message).0))
|
||||||
|
|||||||
@@ -101,9 +101,12 @@ pub fn challenge43() -> Option<()> {
|
|||||||
let msg = Bytes::from_utf8("hello, world!");
|
let msg = Bytes::from_utf8("hello, world!");
|
||||||
let params = dsa::DsaParameters::new().ok()?;
|
let params = dsa::DsaParameters::new().ok()?;
|
||||||
let keys = dsa::DsaKeys::new(¶ms).ok()?;
|
let keys = dsa::DsaKeys::new(¶ms).ok()?;
|
||||||
let s = keys.sign(¶ms, &msg).ok()?;
|
let sig = keys.sign(¶ms, &msg).ok()?;
|
||||||
let r = keys.verify(¶ms, &msg, &s).ok()?;
|
let result = keys.verify(¶ms, &msg, &sig).ok()?;
|
||||||
assert!(r, "verify failed unexpectedly");
|
assert!(result, "verify failed unexpectedly");
|
||||||
|
|
||||||
|
let recovered_x = dsa::recover_x(¶ms, &msg, &sig).ok()?;
|
||||||
|
assert_eq!(recovered_x, keys.x, "DSA recovery failed");
|
||||||
|
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user