|
|
|
@ -555,14 +555,10 @@ impl SqrtField for Fr {
|
|
|
|
|
fn sqrt(&self) -> Option<Self> { |
|
|
|
|
// Tonelli-Shank's algorithm for q mod 16 = 1
|
|
|
|
|
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
|
|
|
|
|
|
|
|
|
|
if self.is_zero() { |
|
|
|
|
return Some(*self); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if let QNonResidue = self.legendre() { |
|
|
|
|
None |
|
|
|
|
} else { |
|
|
|
|
match self.legendre() { |
|
|
|
|
Zero => Some(*self), |
|
|
|
|
QNonResidue => None, |
|
|
|
|
QResidue => { |
|
|
|
|
let mut c = Fr(ROOT_OF_UNITY); |
|
|
|
|
// r = self^((t + 1) // 2)
|
|
|
|
|
let mut r = self.pow([0x7fff2dff80000000, 0x4d0ec02a9ded201, 0x94cebea4199cec04, 0x39f6d3a9]); |
|
|
|
@ -596,6 +592,7 @@ impl SqrtField for Fr {
|
|
|
|
|
Some(r) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl LegendreField for Fr { |
|
|
|
@ -606,6 +603,7 @@ impl LegendreField for Fr {
|
|
|
|
|
else { QNonResidue } |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[cfg(test)] |
|
|
|
|
use rand::{SeedableRng, XorShiftRng, Rand}; |
|
|
|
|
|
|
|
|
|