mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-18 16:55:16 +00:00
Conditional negate (#90)
* Reorder tests in dalek-ff-group * Add required method for ConditionallyNegatable Adds lifetime bound implementation `Neg` for borrowed FieldElements in dalek-ff-group.
This commit is contained in:
parent
45912d6837
commit
a2aa182cc4
1 changed files with 35 additions and 10 deletions
|
@ -2,7 +2,7 @@ use core::ops::{Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign};
|
||||||
|
|
||||||
use rand_core::RngCore;
|
use rand_core::RngCore;
|
||||||
|
|
||||||
use subtle::{Choice, CtOption, ConstantTimeEq, ConditionallySelectable};
|
use subtle::{Choice, CtOption, ConstantTimeEq, ConditionallyNegatable, ConditionallySelectable};
|
||||||
|
|
||||||
use crypto_bigint::{Encoding, U256, U512};
|
use crypto_bigint::{Encoding, U256, U512};
|
||||||
|
|
||||||
|
@ -50,6 +50,13 @@ impl Neg for FieldElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Neg for &'a FieldElement {
|
||||||
|
type Output = FieldElement;
|
||||||
|
fn neg(self) -> Self::Output {
|
||||||
|
(*self).neg()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Field for FieldElement {
|
impl Field for FieldElement {
|
||||||
fn random(mut rng: impl RngCore) -> Self {
|
fn random(mut rng: impl RngCore) -> Self {
|
||||||
let mut bytes = [0; 64];
|
let mut bytes = [0; 64];
|
||||||
|
@ -174,7 +181,7 @@ impl FieldElement {
|
||||||
r.conditional_assign(&r_prime, flipped_sign | flipped_sign_i);
|
r.conditional_assign(&r_prime, flipped_sign | flipped_sign_i);
|
||||||
|
|
||||||
let r_is_negative = r.is_odd();
|
let r_is_negative = r.is_odd();
|
||||||
r.conditional_assign(&(-r), r_is_negative);
|
r.conditional_negate(r_is_negative);
|
||||||
|
|
||||||
let was_non_zero_square = correct_sign | flipped_sign;
|
let was_non_zero_square = correct_sign | flipped_sign;
|
||||||
|
|
||||||
|
@ -182,6 +189,32 @@ impl FieldElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_conditional_negate() {
|
||||||
|
let one = FieldElement::one();
|
||||||
|
let true_choice = choice(true);
|
||||||
|
let false_choice = choice(false);
|
||||||
|
|
||||||
|
let mut var = one;
|
||||||
|
|
||||||
|
var.conditional_negate(false_choice);
|
||||||
|
assert_eq!(var, FieldElement::one());
|
||||||
|
|
||||||
|
var.conditional_negate(true_choice);
|
||||||
|
assert_eq!(var, -FieldElement::one());
|
||||||
|
|
||||||
|
var.conditional_negate(false_choice);
|
||||||
|
assert_eq!(var, -FieldElement::one());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_edwards_d() {
|
||||||
|
let a = -FieldElement(U256::from_u32(121665));
|
||||||
|
let b = FieldElement(U256::from_u32(121666));
|
||||||
|
|
||||||
|
assert_eq!(EDWARDS_D, a * b.invert().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_odd() {
|
fn test_is_odd() {
|
||||||
assert_eq!(0, FieldElement::zero().is_odd().unwrap_u8());
|
assert_eq!(0, FieldElement::zero().is_odd().unwrap_u8());
|
||||||
|
@ -194,14 +227,6 @@ fn test_is_odd() {
|
||||||
assert_eq!(1, (-FieldElement::one().double()).is_odd().unwrap_u8());
|
assert_eq!(1, (-FieldElement::one().double()).is_odd().unwrap_u8());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_edwards_d() {
|
|
||||||
let a = -FieldElement(U256::from_u32(121665));
|
|
||||||
let b = FieldElement(U256::from_u32(121666));
|
|
||||||
|
|
||||||
assert_eq!(EDWARDS_D, a * b.invert().unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mul() {
|
fn test_mul() {
|
||||||
assert_eq!(FieldElement(FIELD_MODULUS) * FieldElement::one(), FieldElement::zero());
|
assert_eq!(FieldElement(FIELD_MODULUS) * FieldElement::one(), FieldElement::zero());
|
||||||
|
|
Loading…
Reference in a new issue