Rename Maybe to CtOption, and do not expose submodule.
This commit is contained in:
parent
26de2362db
commit
390aa23db2
|
@ -1,13 +1,13 @@
|
||||||
//! This module provides a "Maybe" abstraction as a constant-time
|
//! This module provides a "CtOption" abstraction as a constant-time
|
||||||
//! alternative for APIs that want to return optional values.
|
//! alternative for APIs that want to return optional values.
|
||||||
//! Ideally, this would be merged into upstream `subtle` at some
|
//! Ideally, this would be merged into upstream `subtle` at some
|
||||||
//! point.
|
//! point.
|
||||||
|
|
||||||
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
|
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
|
||||||
|
|
||||||
/// The `Maybe<T>` type represents an optional value similar to the
|
/// The `CtOption<T>` type represents an optional value similar to the
|
||||||
/// [`Option<T>`](core::option::Option) type but is intended for
|
/// [`Option<T>`](core::option::Option) type but is intended for
|
||||||
/// use in constant time APIs. Any given `Maybe<T>` is either
|
/// use in constant time APIs. Any given `CtOption<T>` is either
|
||||||
/// `Some` or `None`, but unlike `Option<T>` these variants are
|
/// `Some` or `None`, but unlike `Option<T>` these variants are
|
||||||
/// not exposed. The `is_some()` method is used to determine if the
|
/// not exposed. The `is_some()` method is used to determine if the
|
||||||
/// value is `Some`, and `unwrap_or`/`unwrap_or_else` methods are
|
/// value is `Some`, and `unwrap_or`/`unwrap_or_else` methods are
|
||||||
|
@ -21,20 +21,20 @@ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
|
||||||
/// about the result in constant time, and returning an incorrect
|
/// about the result in constant time, and returning an incorrect
|
||||||
/// value burdens the caller and increases the chance of bugs.
|
/// value burdens the caller and increases the chance of bugs.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct Maybe<T> {
|
pub struct CtOption<T> {
|
||||||
value: T,
|
value: T,
|
||||||
is_some: Choice,
|
is_some: Choice,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Maybe<T> {
|
impl<T> CtOption<T> {
|
||||||
/// This method is used to construct a new `Maybe<T>` and takes
|
/// This method is used to construct a new `CtOption<T>` and takes
|
||||||
/// a value of type `T`, and a `Choice` that determines whether
|
/// a value of type `T`, and a `Choice` that determines whether
|
||||||
/// the optional value should be `Some` or not. If `is_some` is
|
/// the optional value should be `Some` or not. If `is_some` is
|
||||||
/// false, the value will still be stored but its value is never
|
/// false, the value will still be stored but its value is never
|
||||||
/// exposed.
|
/// exposed.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(value: T, is_some: Choice) -> Maybe<T> {
|
pub fn new(value: T, is_some: Choice) -> CtOption<T> {
|
||||||
Maybe { value, is_some }
|
CtOption { value, is_some }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This returns the underlying value but panics if it
|
/// This returns the underlying value but panics if it
|
||||||
|
@ -80,7 +80,7 @@ impl<T> Maybe<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a `None` value if the option is `None`, otherwise
|
/// Returns a `None` value if the option is `None`, otherwise
|
||||||
/// returns a `Maybe` enclosing the value of the provided closure.
|
/// returns a `CtOption` enclosing the value of the provided closure.
|
||||||
/// The closure is given the enclosed value or, if the option is
|
/// The closure is given the enclosed value or, if the option is
|
||||||
/// `None`, it is provided a dummy value computed using
|
/// `None`, it is provided a dummy value computed using
|
||||||
/// `Default::default()`.
|
/// `Default::default()`.
|
||||||
|
@ -88,12 +88,12 @@ impl<T> Maybe<T> {
|
||||||
/// This operates in constant time, because the provided closure
|
/// This operates in constant time, because the provided closure
|
||||||
/// is always called.
|
/// is always called.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn map<U, F>(self, f: F) -> Maybe<U>
|
pub fn map<U, F>(self, f: F) -> CtOption<U>
|
||||||
where
|
where
|
||||||
T: Default + ConditionallySelectable,
|
T: Default + ConditionallySelectable,
|
||||||
F: FnOnce(T) -> U,
|
F: FnOnce(T) -> U,
|
||||||
{
|
{
|
||||||
Maybe::new(
|
CtOption::new(
|
||||||
f(T::conditional_select(
|
f(T::conditional_select(
|
||||||
&T::default(),
|
&T::default(),
|
||||||
&self.value,
|
&self.value,
|
||||||
|
@ -111,10 +111,10 @@ impl<T> Maybe<T> {
|
||||||
/// This operates in constant time, because the provided closure
|
/// This operates in constant time, because the provided closure
|
||||||
/// is always called.
|
/// is always called.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn and_then<U, F>(self, f: F) -> Maybe<U>
|
pub fn and_then<U, F>(self, f: F) -> CtOption<U>
|
||||||
where
|
where
|
||||||
T: Default + ConditionallySelectable,
|
T: Default + ConditionallySelectable,
|
||||||
F: FnOnce(T) -> Maybe<U>,
|
F: FnOnce(T) -> CtOption<U>,
|
||||||
{
|
{
|
||||||
let mut tmp = f(T::conditional_select(
|
let mut tmp = f(T::conditional_select(
|
||||||
&T::default(),
|
&T::default(),
|
||||||
|
@ -127,9 +127,9 @@ impl<T> Maybe<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ConditionallySelectable> ConditionallySelectable for Maybe<T> {
|
impl<T: ConditionallySelectable> ConditionallySelectable for CtOption<T> {
|
||||||
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
|
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
|
||||||
Maybe::new(
|
CtOption::new(
|
||||||
T::conditional_select(&a.value, &b.value, choice),
|
T::conditional_select(&a.value, &b.value, choice),
|
||||||
// TODO: subtle crate currently doesn't implement ConditionallySelectable
|
// TODO: subtle crate currently doesn't implement ConditionallySelectable
|
||||||
// for Choice so we must unwrap these manually.
|
// for Choice so we must unwrap these manually.
|
||||||
|
@ -142,11 +142,11 @@ impl<T: ConditionallySelectable> ConditionallySelectable for Maybe<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ConstantTimeEq> ConstantTimeEq for Maybe<T> {
|
impl<T: ConstantTimeEq> ConstantTimeEq for CtOption<T> {
|
||||||
/// Two `Maybe<T>`s are equal if they are both `Some` and
|
/// Two `CtOption<T>`s are equal if they are both `Some` and
|
||||||
/// their values are equal, or both `None`.
|
/// their values are equal, or both `None`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ct_eq(&self, rhs: &Maybe<T>) -> Choice {
|
fn ct_eq(&self, rhs: &CtOption<T>) -> Choice {
|
||||||
let a = self.is_some();
|
let a = self.is_some();
|
||||||
let b = rhs.is_some();
|
let b = rhs.is_some();
|
||||||
|
|
||||||
|
@ -155,11 +155,11 @@ impl<T: ConstantTimeEq> ConstantTimeEq for Maybe<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_maybe() {
|
fn test_ctoption() {
|
||||||
let a = Maybe::new(10, Choice::from(1));
|
let a = CtOption::new(10, Choice::from(1));
|
||||||
let b = Maybe::new(9, Choice::from(1));
|
let b = CtOption::new(9, Choice::from(1));
|
||||||
let c = Maybe::new(10, Choice::from(0));
|
let c = CtOption::new(10, Choice::from(0));
|
||||||
let d = Maybe::new(9, Choice::from(0));
|
let d = CtOption::new(9, Choice::from(0));
|
||||||
|
|
||||||
// Test is_some / is_none
|
// Test is_some / is_none
|
||||||
assert!(bool::from(a.is_some()));
|
assert!(bool::from(a.is_some()));
|
||||||
|
@ -186,16 +186,16 @@ fn test_maybe() {
|
||||||
assert!(bool::from(c.ct_eq(&d)));
|
assert!(bool::from(c.ct_eq(&d)));
|
||||||
|
|
||||||
// Test unwrap_or
|
// Test unwrap_or
|
||||||
assert_eq!(Maybe::new(1, Choice::from(1)).unwrap_or(2), 1);
|
assert_eq!(CtOption::new(1, Choice::from(1)).unwrap_or(2), 1);
|
||||||
assert_eq!(Maybe::new(1, Choice::from(0)).unwrap_or(2), 2);
|
assert_eq!(CtOption::new(1, Choice::from(0)).unwrap_or(2), 2);
|
||||||
|
|
||||||
// Test unwrap_or_else
|
// Test unwrap_or_else
|
||||||
assert_eq!(Maybe::new(1, Choice::from(1)).unwrap_or_else(|| 2), 1);
|
assert_eq!(CtOption::new(1, Choice::from(1)).unwrap_or_else(|| 2), 1);
|
||||||
assert_eq!(Maybe::new(1, Choice::from(0)).unwrap_or_else(|| 2), 2);
|
assert_eq!(CtOption::new(1, Choice::from(0)).unwrap_or_else(|| 2), 2);
|
||||||
|
|
||||||
// Test map
|
// Test map
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Maybe::new(1, Choice::from(1))
|
CtOption::new(1, Choice::from(1))
|
||||||
.map(|v| {
|
.map(|v| {
|
||||||
assert_eq!(v, 1);
|
assert_eq!(v, 1);
|
||||||
2
|
2
|
||||||
|
@ -204,7 +204,7 @@ fn test_maybe() {
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Maybe::new(1, Choice::from(0))
|
CtOption::new(1, Choice::from(0))
|
||||||
.map(|_| 2)
|
.map(|_| 2)
|
||||||
.is_none()
|
.is_none()
|
||||||
.unwrap_u8(),
|
.unwrap_u8(),
|
||||||
|
@ -213,35 +213,35 @@ fn test_maybe() {
|
||||||
|
|
||||||
// Test and_then
|
// Test and_then
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Maybe::new(1, Choice::from(1))
|
CtOption::new(1, Choice::from(1))
|
||||||
.and_then(|v| {
|
.and_then(|v| {
|
||||||
assert_eq!(v, 1);
|
assert_eq!(v, 1);
|
||||||
Maybe::new(2, Choice::from(0))
|
CtOption::new(2, Choice::from(0))
|
||||||
})
|
})
|
||||||
.is_none()
|
.is_none()
|
||||||
.unwrap_u8(),
|
.unwrap_u8(),
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Maybe::new(1, Choice::from(1))
|
CtOption::new(1, Choice::from(1))
|
||||||
.and_then(|v| {
|
.and_then(|v| {
|
||||||
assert_eq!(v, 1);
|
assert_eq!(v, 1);
|
||||||
Maybe::new(2, Choice::from(1))
|
CtOption::new(2, Choice::from(1))
|
||||||
})
|
})
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Maybe::new(1, Choice::from(0))
|
CtOption::new(1, Choice::from(0))
|
||||||
.and_then(|_| Maybe::new(2, Choice::from(0)))
|
.and_then(|_| CtOption::new(2, Choice::from(0)))
|
||||||
.is_none()
|
.is_none()
|
||||||
.unwrap_u8(),
|
.unwrap_u8(),
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Maybe::new(1, Choice::from(0))
|
CtOption::new(1, Choice::from(0))
|
||||||
.and_then(|_| Maybe::new(2, Choice::from(1)))
|
.and_then(|_| CtOption::new(2, Choice::from(1)))
|
||||||
.is_none()
|
.is_none()
|
||||||
.unwrap_u8(),
|
.unwrap_u8(),
|
||||||
1
|
1
|
||||||
|
@ -250,8 +250,8 @@ fn test_maybe() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn unwrap_none_maybe() {
|
fn unwrap_none_ctoption() {
|
||||||
// This test might fail (in release mode?) if the
|
// This test might fail (in release mode?) if the
|
||||||
// compiler decides to optimize it away.
|
// compiler decides to optimize it away.
|
||||||
Maybe::new(10, Choice::from(0)).unwrap();
|
CtOption::new(10, Choice::from(0)).unwrap();
|
||||||
}
|
}
|
14
src/fq.rs
14
src/fq.rs
|
@ -4,8 +4,8 @@ use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
|
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
|
||||||
|
|
||||||
use crate::maybe::Maybe;
|
|
||||||
use crate::util::{adc, mac, sbb};
|
use crate::util::{adc, mac, sbb};
|
||||||
|
use crate::CtOption;
|
||||||
|
|
||||||
/// Represents an element of `GF(q)`.
|
/// Represents an element of `GF(q)`.
|
||||||
// The internal representation of this type is four 64-bit unsigned
|
// The internal representation of this type is four 64-bit unsigned
|
||||||
|
@ -208,7 +208,7 @@ impl Fq {
|
||||||
/// Attempts to convert a little-endian byte representation of
|
/// Attempts to convert a little-endian byte representation of
|
||||||
/// a field element into an element of `Fq`, failing if the input
|
/// a field element into an element of `Fq`, failing if the input
|
||||||
/// is not canonical (is not smaller than q).
|
/// is not canonical (is not smaller than q).
|
||||||
pub fn from_bytes(bytes: [u8; 32]) -> Maybe<Fq> {
|
pub fn from_bytes(bytes: [u8; 32]) -> CtOption<Fq> {
|
||||||
let mut tmp = Fq([0, 0, 0, 0]);
|
let mut tmp = Fq([0, 0, 0, 0]);
|
||||||
|
|
||||||
tmp.0[0] = LittleEndian::read_u64(&bytes[0..8]);
|
tmp.0[0] = LittleEndian::read_u64(&bytes[0..8]);
|
||||||
|
@ -231,7 +231,7 @@ impl Fq {
|
||||||
// (a.R^{-1} * R^2) / R = a.R
|
// (a.R^{-1} * R^2) / R = a.R
|
||||||
tmp *= &R2;
|
tmp *= &R2;
|
||||||
|
|
||||||
Maybe::new(tmp, Choice::from(is_some))
|
CtOption::new(tmp, Choice::from(is_some))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts an element of `Fq` into a byte representation in
|
/// Converts an element of `Fq` into a byte representation in
|
||||||
|
@ -324,7 +324,7 @@ impl Fq {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the square root of this element, if it exists.
|
/// Computes the square root of this element, if it exists.
|
||||||
pub fn sqrt(&self) -> Maybe<Self> {
|
pub fn sqrt(&self) -> CtOption<Self> {
|
||||||
// Tonelli-Shank's algorithm for q mod 16 = 1
|
// Tonelli-Shank's algorithm for q mod 16 = 1
|
||||||
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
|
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ impl Fq {
|
||||||
v = k;
|
v = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe::new(
|
CtOption::new(
|
||||||
x,
|
x,
|
||||||
(&x * &x).ct_eq(self), // Only return Some if it's the square root.
|
(&x * &x).ct_eq(self), // Only return Some if it's the square root.
|
||||||
)
|
)
|
||||||
|
@ -409,7 +409,7 @@ impl Fq {
|
||||||
|
|
||||||
/// Computes the multiplicative inverse of this element,
|
/// Computes the multiplicative inverse of this element,
|
||||||
/// failing if the element is zero.
|
/// failing if the element is zero.
|
||||||
pub fn invert(&self) -> Maybe<Self> {
|
pub fn invert(&self) -> CtOption<Self> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn square_assign_multi(n: &mut Fq, num_times: usize) {
|
fn square_assign_multi(n: &mut Fq, num_times: usize) {
|
||||||
for _ in 0..num_times {
|
for _ in 0..num_times {
|
||||||
|
@ -504,7 +504,7 @@ impl Fq {
|
||||||
square_assign_multi(&mut t0, 5);
|
square_assign_multi(&mut t0, 5);
|
||||||
t0.mul_assign(&t1);
|
t0.mul_assign(&t1);
|
||||||
|
|
||||||
Maybe::new(t0, !self.ct_eq(&Self::zero()))
|
CtOption::new(t0, !self.ct_eq(&Self::zero()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
14
src/fr.rs
14
src/fr.rs
|
@ -4,8 +4,8 @@ use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
|
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
|
||||||
|
|
||||||
use crate::maybe::Maybe;
|
|
||||||
use crate::util::{adc, mac, sbb};
|
use crate::util::{adc, mac, sbb};
|
||||||
|
use crate::CtOption;
|
||||||
|
|
||||||
/// Represents an element of `GF(r)`.
|
/// Represents an element of `GF(r)`.
|
||||||
// The internal representation of this type is four 64-bit unsigned
|
// The internal representation of this type is four 64-bit unsigned
|
||||||
|
@ -190,7 +190,7 @@ impl Fr {
|
||||||
/// Attempts to convert a little-endian byte representation of
|
/// Attempts to convert a little-endian byte representation of
|
||||||
/// a field element into an element of `Fr`, failing if the input
|
/// a field element into an element of `Fr`, failing if the input
|
||||||
/// is not canonical (is not smaller than r).
|
/// is not canonical (is not smaller than r).
|
||||||
pub fn from_bytes(bytes: [u8; 32]) -> Maybe<Fr> {
|
pub fn from_bytes(bytes: [u8; 32]) -> CtOption<Fr> {
|
||||||
let mut tmp = Fr([0, 0, 0, 0]);
|
let mut tmp = Fr([0, 0, 0, 0]);
|
||||||
|
|
||||||
tmp.0[0] = LittleEndian::read_u64(&bytes[0..8]);
|
tmp.0[0] = LittleEndian::read_u64(&bytes[0..8]);
|
||||||
|
@ -213,7 +213,7 @@ impl Fr {
|
||||||
// (a.R^{-1} * R^2) / R = a.R
|
// (a.R^{-1} * R^2) / R = a.R
|
||||||
tmp *= &R2;
|
tmp *= &R2;
|
||||||
|
|
||||||
Maybe::new(tmp, Choice::from(is_some))
|
CtOption::new(tmp, Choice::from(is_some))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts an element of `Fr` into a byte representation in
|
/// Converts an element of `Fr` into a byte representation in
|
||||||
|
@ -306,7 +306,7 @@ impl Fr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the square root of this element, if it exists.
|
/// Computes the square root of this element, if it exists.
|
||||||
pub fn sqrt(&self) -> Maybe<Self> {
|
pub fn sqrt(&self) -> CtOption<Self> {
|
||||||
// Because r = 3 (mod 4)
|
// Because r = 3 (mod 4)
|
||||||
// sqrt can be done with only one exponentiation,
|
// sqrt can be done with only one exponentiation,
|
||||||
// via the computation of self^((r + 1) // 4) (mod r)
|
// via the computation of self^((r + 1) // 4) (mod r)
|
||||||
|
@ -317,7 +317,7 @@ impl Fr {
|
||||||
0x039f6d3a994cebea,
|
0x039f6d3a994cebea,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Maybe::new(
|
CtOption::new(
|
||||||
sqrt,
|
sqrt,
|
||||||
(&sqrt * &sqrt).ct_eq(self), // Only return Some if it's the square root.
|
(&sqrt * &sqrt).ct_eq(self), // Only return Some if it's the square root.
|
||||||
)
|
)
|
||||||
|
@ -360,7 +360,7 @@ impl Fr {
|
||||||
|
|
||||||
/// Computes the multiplicative inverse of this element,
|
/// Computes the multiplicative inverse of this element,
|
||||||
/// failing if the element is zero.
|
/// failing if the element is zero.
|
||||||
pub fn invert(&self) -> Maybe<Self> {
|
pub fn invert(&self) -> CtOption<Self> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn square_assign_multi(n: &mut Fr, num_times: usize) {
|
fn square_assign_multi(n: &mut Fr, num_times: usize) {
|
||||||
for _ in 0..num_times {
|
for _ in 0..num_times {
|
||||||
|
@ -462,7 +462,7 @@ impl Fr {
|
||||||
square_assign_multi(&mut t0, 7);
|
square_assign_multi(&mut t0, 7);
|
||||||
t0.mul_assign(&t1);
|
t0.mul_assign(&t1);
|
||||||
|
|
||||||
Maybe::new(t0, !self.ct_eq(&Self::zero()))
|
CtOption::new(t0, !self.ct_eq(&Self::zero()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -41,8 +41,8 @@ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
pub mod maybe;
|
mod ctoption;
|
||||||
use maybe::Maybe;
|
pub use ctoption::CtOption;
|
||||||
|
|
||||||
mod fq;
|
mod fq;
|
||||||
mod fr;
|
mod fr;
|
||||||
|
@ -318,7 +318,7 @@ impl AffinePoint {
|
||||||
/// Attempts to interpret a byte representation of an
|
/// Attempts to interpret a byte representation of an
|
||||||
/// affine point, failing if the element is not on
|
/// affine point, failing if the element is not on
|
||||||
/// the curve or non-canonical.
|
/// the curve or non-canonical.
|
||||||
pub fn from_bytes(mut b: [u8; 32]) -> Maybe<Self> {
|
pub fn from_bytes(mut b: [u8; 32]) -> CtOption<Self> {
|
||||||
// Grab the sign bit from the representation
|
// Grab the sign bit from the representation
|
||||||
let sign = b[31] >> 7;
|
let sign = b[31] >> 7;
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ impl AffinePoint {
|
||||||
let u_negated = -u;
|
let u_negated = -u;
|
||||||
let final_u = Fq::conditional_select(&u, &u_negated, flip_sign);
|
let final_u = Fq::conditional_select(&u, &u_negated, flip_sign);
|
||||||
|
|
||||||
Maybe::new(AffinePoint { u: final_u, v }, Choice::from(1u8))
|
CtOption::new(AffinePoint { u: final_u, v }, Choice::from(1u8))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue