mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-07-31 12:31:22 +00:00
cargo fmt zcash_primitives
This commit is contained in:
@@ -9,7 +9,12 @@ use rand_core::RngCore;
|
||||
use super::ToUniform;
|
||||
|
||||
// s = 6554484396890773809930967563523245729705921265872317281365359162392183254199
|
||||
const MODULUS: FsRepr = FsRepr([0xd0970e5ed6f72cb7, 0xa6682093ccc81082, 0x6673b0101343b00, 0xe7db4ea6533afa9]);
|
||||
const MODULUS: FsRepr = FsRepr([
|
||||
0xd0970e5ed6f72cb7,
|
||||
0xa6682093ccc81082,
|
||||
0x6673b0101343b00,
|
||||
0xe7db4ea6533afa9,
|
||||
]);
|
||||
|
||||
// The number of bits needed to represent the modulus.
|
||||
const MODULUS_BITS: u32 = 252;
|
||||
@@ -19,32 +24,56 @@ const MODULUS_BITS: u32 = 252;
|
||||
const REPR_SHAVE_BITS: u32 = 4;
|
||||
|
||||
// R = 2**256 % s
|
||||
const R: FsRepr = FsRepr([0x25f80bb3b99607d9, 0xf315d62f66b6e750, 0x932514eeeb8814f4, 0x9a6fc6f479155c6]);
|
||||
const R: FsRepr = FsRepr([
|
||||
0x25f80bb3b99607d9,
|
||||
0xf315d62f66b6e750,
|
||||
0x932514eeeb8814f4,
|
||||
0x9a6fc6f479155c6,
|
||||
]);
|
||||
|
||||
// R2 = R^2 % s
|
||||
const R2: FsRepr = FsRepr([0x67719aa495e57731, 0x51b0cef09ce3fc26, 0x69dab7fac026e9a5, 0x4f6547b8d127688]);
|
||||
const R2: FsRepr = FsRepr([
|
||||
0x67719aa495e57731,
|
||||
0x51b0cef09ce3fc26,
|
||||
0x69dab7fac026e9a5,
|
||||
0x4f6547b8d127688,
|
||||
]);
|
||||
|
||||
// INV = -(s^{-1} mod 2^64) mod s
|
||||
const INV: u64 = 0x1ba3a358ef788ef9;
|
||||
|
||||
// GENERATOR = 6 (multiplicative generator of r-1 order, that is also quadratic nonresidue)
|
||||
const GENERATOR: FsRepr = FsRepr([0x720b1b19d49ea8f1, 0xbf4aa36101f13a58, 0x5fa8cc968193ccbb, 0xe70cbdc7dccf3ac]);
|
||||
const GENERATOR: FsRepr = FsRepr([
|
||||
0x720b1b19d49ea8f1,
|
||||
0xbf4aa36101f13a58,
|
||||
0x5fa8cc968193ccbb,
|
||||
0xe70cbdc7dccf3ac,
|
||||
]);
|
||||
|
||||
// 2^S * t = MODULUS - 1 with t odd
|
||||
const S: u32 = 1;
|
||||
|
||||
// 2^S root of unity computed by GENERATOR^t
|
||||
const ROOT_OF_UNITY: FsRepr = FsRepr([0xaa9f02ab1d6124de, 0xb3524a6466112932, 0x7342261215ac260b, 0x4d6b87b1da259e2]);
|
||||
const ROOT_OF_UNITY: FsRepr = FsRepr([
|
||||
0xaa9f02ab1d6124de,
|
||||
0xb3524a6466112932,
|
||||
0x7342261215ac260b,
|
||||
0x4d6b87b1da259e2,
|
||||
]);
|
||||
|
||||
// -((2**256) mod s) mod s
|
||||
const NEGATIVE_ONE: Fs = Fs(FsRepr([0xaa9f02ab1d6124de, 0xb3524a6466112932, 0x7342261215ac260b, 0x4d6b87b1da259e2]));
|
||||
const NEGATIVE_ONE: Fs = Fs(FsRepr([
|
||||
0xaa9f02ab1d6124de,
|
||||
0xb3524a6466112932,
|
||||
0x7342261215ac260b,
|
||||
0x4d6b87b1da259e2,
|
||||
]));
|
||||
|
||||
/// This is the underlying representation of an element of `Fs`.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
|
||||
pub struct FsRepr(pub [u64; 4]);
|
||||
|
||||
impl ::std::fmt::Display for FsRepr
|
||||
{
|
||||
impl ::std::fmt::Display for FsRepr {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
try!(write!(f, "0x"));
|
||||
for i in self.0.iter().rev() {
|
||||
@@ -83,9 +112,9 @@ impl Ord for FsRepr {
|
||||
fn cmp(&self, other: &FsRepr) -> ::std::cmp::Ordering {
|
||||
for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) {
|
||||
if a < b {
|
||||
return ::std::cmp::Ordering::Less
|
||||
return ::std::cmp::Ordering::Less;
|
||||
} else if a > b {
|
||||
return ::std::cmp::Ordering::Greater
|
||||
return ::std::cmp::Ordering::Greater;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,8 +256,7 @@ impl PrimeFieldRepr for FsRepr {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Fs(FsRepr);
|
||||
|
||||
impl ::std::fmt::Display for Fs
|
||||
{
|
||||
impl ::std::fmt::Display for Fs {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
write!(f, "Fs({})", self.into_repr())
|
||||
}
|
||||
@@ -256,9 +284,16 @@ impl PrimeField for Fs {
|
||||
|
||||
fn into_repr(&self) -> FsRepr {
|
||||
let mut r = *self;
|
||||
r.mont_reduce((self.0).0[0], (self.0).0[1],
|
||||
(self.0).0[2], (self.0).0[3],
|
||||
0, 0, 0, 0);
|
||||
r.mont_reduce(
|
||||
(self.0).0[0],
|
||||
(self.0).0[1],
|
||||
(self.0).0[2],
|
||||
(self.0).0[3],
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
r.0
|
||||
}
|
||||
|
||||
@@ -296,7 +331,7 @@ impl Field for Fs {
|
||||
tmp.0.as_mut()[3] &= 0xffffffffffffffff >> REPR_SHAVE_BITS;
|
||||
|
||||
if tmp.is_valid() {
|
||||
return tmp
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -414,8 +449,7 @@ impl Field for Fs {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, other: &Fs)
|
||||
{
|
||||
fn mul_assign(&mut self, other: &Fs) {
|
||||
let mut carry = 0;
|
||||
let r0 = mac_with_carry(0, (self.0).0[0], (other.0).0[0], &mut carry);
|
||||
let r1 = mac_with_carry(0, (self.0).0[0], (other.0).0[1], &mut carry);
|
||||
@@ -444,8 +478,7 @@ impl Field for Fs {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn square(&mut self)
|
||||
{
|
||||
fn square(&mut self) {
|
||||
let mut carry = 0;
|
||||
let r1 = mac_with_carry(0, (self.0).0[0], (self.0).0[1], &mut carry);
|
||||
let r2 = mac_with_carry(0, (self.0).0[0], (self.0).0[2], &mut carry);
|
||||
@@ -507,9 +540,8 @@ impl Fs {
|
||||
mut r4: u64,
|
||||
mut r5: u64,
|
||||
mut r6: u64,
|
||||
mut r7: u64
|
||||
)
|
||||
{
|
||||
mut r7: u64,
|
||||
) {
|
||||
// The Montgomery reduction here is based on Algorithm 14.32 in
|
||||
// Handbook of Applied Cryptography
|
||||
// <http://cacr.uwaterloo.ca/hac/about/chap14.pdf>.
|
||||
@@ -579,13 +611,21 @@ impl ToUniform for Fs {
|
||||
}
|
||||
|
||||
impl SqrtField for Fs {
|
||||
|
||||
fn legendre(&self) -> LegendreSymbol {
|
||||
// s = self^((s - 1) // 2)
|
||||
let s = self.pow([0x684b872f6b7b965b, 0x53341049e6640841, 0x83339d80809a1d80, 0x73eda753299d7d4]);
|
||||
if s == Self::zero() { Zero }
|
||||
else if s == Self::one() { QuadraticResidue }
|
||||
else { QuadraticNonResidue }
|
||||
let s = self.pow([
|
||||
0x684b872f6b7b965b,
|
||||
0x53341049e6640841,
|
||||
0x83339d80809a1d80,
|
||||
0x73eda753299d7d4,
|
||||
]);
|
||||
if s == Self::zero() {
|
||||
Zero
|
||||
} else if s == Self::one() {
|
||||
QuadraticResidue
|
||||
} else {
|
||||
QuadraticNonResidue
|
||||
}
|
||||
}
|
||||
|
||||
fn sqrt(&self) -> Option<Self> {
|
||||
@@ -593,24 +633,25 @@ impl SqrtField for Fs {
|
||||
// https://eprint.iacr.org/2012/685.pdf (page 9, algorithm 2)
|
||||
|
||||
// a1 = self^((s - 3) // 4)
|
||||
let mut a1 = self.pow([0xb425c397b5bdcb2d, 0x299a0824f3320420, 0x4199cec0404d0ec0, 0x39f6d3a994cebea]);
|
||||
let mut a1 = self.pow([
|
||||
0xb425c397b5bdcb2d,
|
||||
0x299a0824f3320420,
|
||||
0x4199cec0404d0ec0,
|
||||
0x39f6d3a994cebea,
|
||||
]);
|
||||
let mut a0 = a1;
|
||||
a0.square();
|
||||
a0.mul_assign(self);
|
||||
|
||||
if a0 == NEGATIVE_ONE
|
||||
{
|
||||
if a0 == NEGATIVE_ONE {
|
||||
None
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
a1.mul_assign(self);
|
||||
Some(a1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_neg_one() {
|
||||
let mut o = Fs::one();
|
||||
@@ -636,12 +677,30 @@ fn test_fs_repr_ordering() {
|
||||
assert!(b > a);
|
||||
}
|
||||
|
||||
assert_equality(FsRepr([9999, 9999, 9999, 9999]), FsRepr([9999, 9999, 9999, 9999]));
|
||||
assert_equality(FsRepr([9999, 9998, 9999, 9999]), FsRepr([9999, 9998, 9999, 9999]));
|
||||
assert_equality(FsRepr([9999, 9999, 9999, 9997]), FsRepr([9999, 9999, 9999, 9997]));
|
||||
assert_lt(FsRepr([9999, 9997, 9999, 9998]), FsRepr([9999, 9997, 9999, 9999]));
|
||||
assert_lt(FsRepr([9999, 9997, 9998, 9999]), FsRepr([9999, 9997, 9999, 9999]));
|
||||
assert_lt(FsRepr([9, 9999, 9999, 9997]), FsRepr([9999, 9999, 9999, 9997]));
|
||||
assert_equality(
|
||||
FsRepr([9999, 9999, 9999, 9999]),
|
||||
FsRepr([9999, 9999, 9999, 9999]),
|
||||
);
|
||||
assert_equality(
|
||||
FsRepr([9999, 9998, 9999, 9999]),
|
||||
FsRepr([9999, 9998, 9999, 9999]),
|
||||
);
|
||||
assert_equality(
|
||||
FsRepr([9999, 9999, 9999, 9997]),
|
||||
FsRepr([9999, 9999, 9999, 9997]),
|
||||
);
|
||||
assert_lt(
|
||||
FsRepr([9999, 9997, 9999, 9998]),
|
||||
FsRepr([9999, 9997, 9999, 9999]),
|
||||
);
|
||||
assert_lt(
|
||||
FsRepr([9999, 9997, 9998, 9999]),
|
||||
FsRepr([9999, 9997, 9999, 9999]),
|
||||
);
|
||||
assert_lt(
|
||||
FsRepr([9, 9999, 9999, 9997]),
|
||||
FsRepr([9999, 9999, 9999, 9997]),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -670,13 +729,34 @@ fn test_fs_repr_is_zero() {
|
||||
|
||||
#[test]
|
||||
fn test_fs_repr_div2() {
|
||||
let mut a = FsRepr([0xbd2920b19c972321, 0x174ed0466a3be37e, 0xd468d5e3b551f0b5, 0xcb67c072733beefc]);
|
||||
let mut a = FsRepr([
|
||||
0xbd2920b19c972321,
|
||||
0x174ed0466a3be37e,
|
||||
0xd468d5e3b551f0b5,
|
||||
0xcb67c072733beefc,
|
||||
]);
|
||||
a.div2();
|
||||
assert_eq!(a, FsRepr([0x5e949058ce4b9190, 0x8ba76823351df1bf, 0x6a346af1daa8f85a, 0x65b3e039399df77e]));
|
||||
assert_eq!(
|
||||
a,
|
||||
FsRepr([
|
||||
0x5e949058ce4b9190,
|
||||
0x8ba76823351df1bf,
|
||||
0x6a346af1daa8f85a,
|
||||
0x65b3e039399df77e
|
||||
])
|
||||
);
|
||||
for _ in 0..10 {
|
||||
a.div2();
|
||||
}
|
||||
assert_eq!(a, FsRepr([0x6fd7a524163392e4, 0x16a2e9da08cd477c, 0xdf9a8d1abc76aa3e, 0x196cf80e4e677d]));
|
||||
assert_eq!(
|
||||
a,
|
||||
FsRepr([
|
||||
0x6fd7a524163392e4,
|
||||
0x16a2e9da08cd477c,
|
||||
0xdf9a8d1abc76aa3e,
|
||||
0x196cf80e4e677d
|
||||
])
|
||||
);
|
||||
for _ in 0..200 {
|
||||
a.div2();
|
||||
}
|
||||
@@ -695,32 +775,46 @@ fn test_fs_repr_div2() {
|
||||
|
||||
#[test]
|
||||
fn test_fs_repr_shr() {
|
||||
let mut a = FsRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1]);
|
||||
let mut a = FsRepr([
|
||||
0xb33fbaec482a283f,
|
||||
0x997de0d3a88cb3df,
|
||||
0x9af62d2a9a0e5525,
|
||||
0x36003ab08de70da1,
|
||||
]);
|
||||
a.shr(0);
|
||||
assert_eq!(
|
||||
a,
|
||||
FsRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1])
|
||||
FsRepr([
|
||||
0xb33fbaec482a283f,
|
||||
0x997de0d3a88cb3df,
|
||||
0x9af62d2a9a0e5525,
|
||||
0x36003ab08de70da1
|
||||
])
|
||||
);
|
||||
a.shr(1);
|
||||
assert_eq!(
|
||||
a,
|
||||
FsRepr([0xd99fdd762415141f, 0xccbef069d44659ef, 0xcd7b16954d072a92, 0x1b001d5846f386d0])
|
||||
FsRepr([
|
||||
0xd99fdd762415141f,
|
||||
0xccbef069d44659ef,
|
||||
0xcd7b16954d072a92,
|
||||
0x1b001d5846f386d0
|
||||
])
|
||||
);
|
||||
a.shr(50);
|
||||
assert_eq!(
|
||||
a,
|
||||
FsRepr([0xbc1a7511967bf667, 0xc5a55341caa4b32f, 0x75611bce1b4335e, 0x6c0])
|
||||
FsRepr([
|
||||
0xbc1a7511967bf667,
|
||||
0xc5a55341caa4b32f,
|
||||
0x75611bce1b4335e,
|
||||
0x6c0
|
||||
])
|
||||
);
|
||||
a.shr(130);
|
||||
assert_eq!(
|
||||
a,
|
||||
FsRepr([0x1d5846f386d0cd7, 0x1b0, 0x0, 0x0])
|
||||
);
|
||||
assert_eq!(a, FsRepr([0x1d5846f386d0cd7, 0x1b0, 0x0, 0x0]));
|
||||
a.shr(64);
|
||||
assert_eq!(
|
||||
a,
|
||||
FsRepr([0x1b0, 0x0, 0x0, 0x0])
|
||||
);
|
||||
assert_eq!(a, FsRepr([0x1b0, 0x0, 0x0, 0x0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -765,9 +859,26 @@ fn test_fs_repr_sub_noborrow() {
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let mut t = FsRepr([0x8e62a7e85264e2c3, 0xb23d34c1941d3ca, 0x5976930b7502dd15, 0x600f3fb517bf5495]);
|
||||
t.sub_noborrow(&FsRepr([0xd64f669809cbc6a4, 0xfa76cb9d90cf7637, 0xfefb0df9038d43b3, 0x298a30c744b31acf]));
|
||||
assert!(t == FsRepr([0xb813415048991c1f, 0x10ad07ae88725d92, 0x5a7b851271759961, 0x36850eedd30c39c5]));
|
||||
let mut t = FsRepr([
|
||||
0x8e62a7e85264e2c3,
|
||||
0xb23d34c1941d3ca,
|
||||
0x5976930b7502dd15,
|
||||
0x600f3fb517bf5495,
|
||||
]);
|
||||
t.sub_noborrow(&FsRepr([
|
||||
0xd64f669809cbc6a4,
|
||||
0xfa76cb9d90cf7637,
|
||||
0xfefb0df9038d43b3,
|
||||
0x298a30c744b31acf,
|
||||
]));
|
||||
assert!(
|
||||
t == FsRepr([
|
||||
0xb813415048991c1f,
|
||||
0x10ad07ae88725d92,
|
||||
0x5a7b851271759961,
|
||||
0x36850eedd30c39c5
|
||||
])
|
||||
);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let mut a = Fs::random(&mut rng).into_repr();
|
||||
@@ -801,9 +912,19 @@ fn test_fs_legendre() {
|
||||
assert_eq!(QuadraticResidue, Fs::one().legendre());
|
||||
assert_eq!(Zero, Fs::zero().legendre());
|
||||
|
||||
let e = FsRepr([0x8385eec23df1f88e, 0x9a01fb412b2dba16, 0x4c928edcdd6c22f, 0x9f2df7ef69ecef9]);
|
||||
let e = FsRepr([
|
||||
0x8385eec23df1f88e,
|
||||
0x9a01fb412b2dba16,
|
||||
0x4c928edcdd6c22f,
|
||||
0x9f2df7ef69ecef9,
|
||||
]);
|
||||
assert_eq!(QuadraticResidue, Fs::from_repr(e).unwrap().legendre());
|
||||
let e = FsRepr([0xe8ed9f299da78568, 0x35efdebc88b2209, 0xc82125cb1f916dbe, 0x6813d2b38c39bd0]);
|
||||
let e = FsRepr([
|
||||
0xe8ed9f299da78568,
|
||||
0x35efdebc88b2209,
|
||||
0xc82125cb1f916dbe,
|
||||
0x6813d2b38c39bd0,
|
||||
]);
|
||||
assert_eq!(QuadraticNonResidue, Fs::from_repr(e).unwrap().legendre());
|
||||
}
|
||||
|
||||
@@ -814,9 +935,27 @@ fn test_fr_repr_add_nocarry() {
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let mut t = FsRepr([0xd64f669809cbc6a4, 0xfa76cb9d90cf7637, 0xfefb0df9038d43b3, 0x298a30c744b31acf]);
|
||||
t.add_nocarry(&FsRepr([0x8e62a7e85264e2c3, 0xb23d34c1941d3ca, 0x5976930b7502dd15, 0x600f3fb517bf5495]));
|
||||
assert_eq!(t, FsRepr([0x64b20e805c30a967, 0x59a9ee9aa114a02, 0x5871a104789020c9, 0x8999707c5c726f65]));
|
||||
let mut t = FsRepr([
|
||||
0xd64f669809cbc6a4,
|
||||
0xfa76cb9d90cf7637,
|
||||
0xfefb0df9038d43b3,
|
||||
0x298a30c744b31acf,
|
||||
]);
|
||||
t.add_nocarry(&FsRepr([
|
||||
0x8e62a7e85264e2c3,
|
||||
0xb23d34c1941d3ca,
|
||||
0x5976930b7502dd15,
|
||||
0x600f3fb517bf5495,
|
||||
]));
|
||||
assert_eq!(
|
||||
t,
|
||||
FsRepr([
|
||||
0x64b20e805c30a967,
|
||||
0x59a9ee9aa114a02,
|
||||
0x5871a104789020c9,
|
||||
0x8999707c5c726f65
|
||||
])
|
||||
);
|
||||
|
||||
// Test for the associativity of addition.
|
||||
for _ in 0..1000 {
|
||||
@@ -868,8 +1007,20 @@ fn test_fs_is_valid() {
|
||||
a.0.sub_noborrow(&FsRepr::from(1));
|
||||
assert!(a.is_valid());
|
||||
assert!(Fs(FsRepr::from(0)).is_valid());
|
||||
assert!(Fs(FsRepr([0xd0970e5ed6f72cb6, 0xa6682093ccc81082, 0x6673b0101343b00, 0xe7db4ea6533afa9])).is_valid());
|
||||
assert!(!Fs(FsRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff])).is_valid());
|
||||
assert!(Fs(FsRepr([
|
||||
0xd0970e5ed6f72cb6,
|
||||
0xa6682093ccc81082,
|
||||
0x6673b0101343b00,
|
||||
0xe7db4ea6533afa9
|
||||
]))
|
||||
.is_valid());
|
||||
assert!(!Fs(FsRepr([
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
]))
|
||||
.is_valid());
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
@@ -886,25 +1037,80 @@ fn test_fs_is_valid() {
|
||||
fn test_fs_add_assign() {
|
||||
{
|
||||
// Random number
|
||||
let mut tmp = Fs::from_str("4577408157467272683998459759522778614363623736323078995109579213719612604198").unwrap();
|
||||
let mut tmp = Fs::from_str(
|
||||
"4577408157467272683998459759522778614363623736323078995109579213719612604198",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(tmp.is_valid());
|
||||
// Test that adding zero has no effect.
|
||||
tmp.add_assign(&Fs(FsRepr::from(0)));
|
||||
assert_eq!(tmp, Fs(FsRepr([0x8e6bfff4722d6e67, 0x5643da5c892044f9, 0x9465f4b281921a69, 0x25f752d3edd7162])));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fs(FsRepr([
|
||||
0x8e6bfff4722d6e67,
|
||||
0x5643da5c892044f9,
|
||||
0x9465f4b281921a69,
|
||||
0x25f752d3edd7162
|
||||
]))
|
||||
);
|
||||
// Add one and test for the result.
|
||||
tmp.add_assign(&Fs(FsRepr::from(1)));
|
||||
assert_eq!(tmp, Fs(FsRepr([0x8e6bfff4722d6e68, 0x5643da5c892044f9, 0x9465f4b281921a69, 0x25f752d3edd7162])));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fs(FsRepr([
|
||||
0x8e6bfff4722d6e68,
|
||||
0x5643da5c892044f9,
|
||||
0x9465f4b281921a69,
|
||||
0x25f752d3edd7162
|
||||
]))
|
||||
);
|
||||
// Add another random number that exercises the reduction.
|
||||
tmp.add_assign(&Fs(FsRepr([0xb634d07bc42d4a70, 0xf724f0c008411f5f, 0x456d4053d865af34, 0x24ce814e8c63027])));
|
||||
assert_eq!(tmp, Fs(FsRepr([0x44a0d070365ab8d8, 0x4d68cb1c91616459, 0xd9d3350659f7c99e, 0x4ac5d4227a3a189])));
|
||||
tmp.add_assign(&Fs(FsRepr([
|
||||
0xb634d07bc42d4a70,
|
||||
0xf724f0c008411f5f,
|
||||
0x456d4053d865af34,
|
||||
0x24ce814e8c63027,
|
||||
])));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fs(FsRepr([
|
||||
0x44a0d070365ab8d8,
|
||||
0x4d68cb1c91616459,
|
||||
0xd9d3350659f7c99e,
|
||||
0x4ac5d4227a3a189
|
||||
]))
|
||||
);
|
||||
// Add one to (s - 1) and test for the result.
|
||||
tmp = Fs(FsRepr([0xd0970e5ed6f72cb6, 0xa6682093ccc81082, 0x6673b0101343b00, 0xe7db4ea6533afa9]));
|
||||
tmp = Fs(FsRepr([
|
||||
0xd0970e5ed6f72cb6,
|
||||
0xa6682093ccc81082,
|
||||
0x6673b0101343b00,
|
||||
0xe7db4ea6533afa9,
|
||||
]));
|
||||
tmp.add_assign(&Fs(FsRepr::from(1)));
|
||||
assert!(tmp.0.is_zero());
|
||||
// Add a random number to another one such that the result is s - 1
|
||||
tmp = Fs(FsRepr([0xa11fda5950ce3636, 0x922e0dbccfe0ca0e, 0xacebb6e215b82d4a, 0x97ffb8cdc3aee93]));
|
||||
tmp.add_assign(&Fs(FsRepr([0x2f7734058628f680, 0x143a12d6fce74674, 0x597b841eeb7c0db6, 0x4fdb95d88f8c115])));
|
||||
assert_eq!(tmp, Fs(FsRepr([0xd0970e5ed6f72cb6, 0xa6682093ccc81082, 0x6673b0101343b00, 0xe7db4ea6533afa9])));
|
||||
tmp = Fs(FsRepr([
|
||||
0xa11fda5950ce3636,
|
||||
0x922e0dbccfe0ca0e,
|
||||
0xacebb6e215b82d4a,
|
||||
0x97ffb8cdc3aee93,
|
||||
]));
|
||||
tmp.add_assign(&Fs(FsRepr([
|
||||
0x2f7734058628f680,
|
||||
0x143a12d6fce74674,
|
||||
0x597b841eeb7c0db6,
|
||||
0x4fdb95d88f8c115,
|
||||
])));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fs(FsRepr([
|
||||
0xd0970e5ed6f72cb6,
|
||||
0xa6682093ccc81082,
|
||||
0x6673b0101343b00,
|
||||
0xe7db4ea6533afa9
|
||||
]))
|
||||
);
|
||||
// Add one to the result and test for it.
|
||||
tmp.add_assign(&Fs(FsRepr::from(1)));
|
||||
assert!(tmp.0.is_zero());
|
||||
@@ -941,23 +1147,72 @@ fn test_fs_add_assign() {
|
||||
fn test_fs_sub_assign() {
|
||||
{
|
||||
// Test arbitrary subtraction that tests reduction.
|
||||
let mut tmp = Fs(FsRepr([0xb384d9f6877afd99, 0x4442513958e1a1c1, 0x352c4b8a95eccc3f, 0x2db62dee4b0f2]));
|
||||
tmp.sub_assign(&Fs(FsRepr([0xec5bd2d13ed6b05a, 0x2adc0ab3a39b5fa, 0x82d3360a493e637e, 0x53ccff4a64d6679])));
|
||||
assert_eq!(tmp, Fs(FsRepr([0x97c015841f9b79f6, 0xe7fcb121eb6ffc49, 0xb8c050814de2a3c1, 0x943c0589dcafa21])));
|
||||
let mut tmp = Fs(FsRepr([
|
||||
0xb384d9f6877afd99,
|
||||
0x4442513958e1a1c1,
|
||||
0x352c4b8a95eccc3f,
|
||||
0x2db62dee4b0f2,
|
||||
]));
|
||||
tmp.sub_assign(&Fs(FsRepr([
|
||||
0xec5bd2d13ed6b05a,
|
||||
0x2adc0ab3a39b5fa,
|
||||
0x82d3360a493e637e,
|
||||
0x53ccff4a64d6679,
|
||||
])));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fs(FsRepr([
|
||||
0x97c015841f9b79f6,
|
||||
0xe7fcb121eb6ffc49,
|
||||
0xb8c050814de2a3c1,
|
||||
0x943c0589dcafa21
|
||||
]))
|
||||
);
|
||||
|
||||
// Test the opposite subtraction which doesn't test reduction.
|
||||
tmp = Fs(FsRepr([0xec5bd2d13ed6b05a, 0x2adc0ab3a39b5fa, 0x82d3360a493e637e, 0x53ccff4a64d6679]));
|
||||
tmp.sub_assign(&Fs(FsRepr([0xb384d9f6877afd99, 0x4442513958e1a1c1, 0x352c4b8a95eccc3f, 0x2db62dee4b0f2])));
|
||||
assert_eq!(tmp, Fs(FsRepr([0x38d6f8dab75bb2c1, 0xbe6b6f71e1581439, 0x4da6ea7fb351973e, 0x539f491c768b587])));
|
||||
tmp = Fs(FsRepr([
|
||||
0xec5bd2d13ed6b05a,
|
||||
0x2adc0ab3a39b5fa,
|
||||
0x82d3360a493e637e,
|
||||
0x53ccff4a64d6679,
|
||||
]));
|
||||
tmp.sub_assign(&Fs(FsRepr([
|
||||
0xb384d9f6877afd99,
|
||||
0x4442513958e1a1c1,
|
||||
0x352c4b8a95eccc3f,
|
||||
0x2db62dee4b0f2,
|
||||
])));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fs(FsRepr([
|
||||
0x38d6f8dab75bb2c1,
|
||||
0xbe6b6f71e1581439,
|
||||
0x4da6ea7fb351973e,
|
||||
0x539f491c768b587
|
||||
]))
|
||||
);
|
||||
|
||||
// Test for sensible results with zero
|
||||
tmp = Fs(FsRepr::from(0));
|
||||
tmp.sub_assign(&Fs(FsRepr::from(0)));
|
||||
assert!(tmp.is_zero());
|
||||
|
||||
tmp = Fs(FsRepr([0x361e16aef5cce835, 0x55bbde2536e274c1, 0x4dc77a63fd15ee75, 0x1e14bb37c14f230]));
|
||||
tmp = Fs(FsRepr([
|
||||
0x361e16aef5cce835,
|
||||
0x55bbde2536e274c1,
|
||||
0x4dc77a63fd15ee75,
|
||||
0x1e14bb37c14f230,
|
||||
]));
|
||||
tmp.sub_assign(&Fs(FsRepr::from(0)));
|
||||
assert_eq!(tmp, Fs(FsRepr([0x361e16aef5cce835, 0x55bbde2536e274c1, 0x4dc77a63fd15ee75, 0x1e14bb37c14f230])));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fs(FsRepr([
|
||||
0x361e16aef5cce835,
|
||||
0x55bbde2536e274c1,
|
||||
0x4dc77a63fd15ee75,
|
||||
0x1e14bb37c14f230
|
||||
]))
|
||||
);
|
||||
}
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
@@ -983,9 +1238,26 @@ fn test_fs_sub_assign() {
|
||||
|
||||
#[test]
|
||||
fn test_fs_mul_assign() {
|
||||
let mut tmp = Fs(FsRepr([0xb433b01287f71744, 0x4eafb86728c4d108, 0xfdd52c14b9dfbe65, 0x2ff1f3434821118]));
|
||||
tmp.mul_assign(&Fs(FsRepr([0xdae00fc63c9fa90f, 0x5a5ed89b96ce21ce, 0x913cd26101bd6f58, 0x3f0822831697fe9])));
|
||||
assert!(tmp == Fs(FsRepr([0xb68ecb61d54d2992, 0x5ff95874defce6a6, 0x3590eb053894657d, 0x53823a118515933])));
|
||||
let mut tmp = Fs(FsRepr([
|
||||
0xb433b01287f71744,
|
||||
0x4eafb86728c4d108,
|
||||
0xfdd52c14b9dfbe65,
|
||||
0x2ff1f3434821118,
|
||||
]));
|
||||
tmp.mul_assign(&Fs(FsRepr([
|
||||
0xdae00fc63c9fa90f,
|
||||
0x5a5ed89b96ce21ce,
|
||||
0x913cd26101bd6f58,
|
||||
0x3f0822831697fe9,
|
||||
])));
|
||||
assert!(
|
||||
tmp == Fs(FsRepr([
|
||||
0xb68ecb61d54d2992,
|
||||
0x5ff95874defce6a6,
|
||||
0x3590eb053894657d,
|
||||
0x53823a118515933
|
||||
]))
|
||||
);
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
@@ -1035,10 +1307,24 @@ fn test_fs_mul_assign() {
|
||||
|
||||
#[test]
|
||||
fn test_fr_squaring() {
|
||||
let mut a = Fs(FsRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xe7db4ea6533afa8]));
|
||||
let mut a = Fs(FsRepr([
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xe7db4ea6533afa8,
|
||||
]));
|
||||
assert!(a.is_valid());
|
||||
a.square();
|
||||
assert_eq!(a, Fs::from_repr(FsRepr([0x12c7f55cbc52fbaa, 0xdedc98a0b5e6ce9e, 0xad2892726a5396a, 0x9fe82af8fee77b3])).unwrap());
|
||||
assert_eq!(
|
||||
a,
|
||||
Fs::from_repr(FsRepr([
|
||||
0x12c7f55cbc52fbaa,
|
||||
0xdedc98a0b5e6ce9e,
|
||||
0xad2892726a5396a,
|
||||
0x9fe82af8fee77b3
|
||||
]))
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
@@ -1185,17 +1471,38 @@ fn test_fs_sqrt() {
|
||||
#[test]
|
||||
fn test_fs_from_into_repr() {
|
||||
// r + 1 should not be in the field
|
||||
assert!(Fs::from_repr(FsRepr([0xd0970e5ed6f72cb8, 0xa6682093ccc81082, 0x6673b0101343b00, 0xe7db4ea6533afa9])).is_err());
|
||||
assert!(Fs::from_repr(FsRepr([
|
||||
0xd0970e5ed6f72cb8,
|
||||
0xa6682093ccc81082,
|
||||
0x6673b0101343b00,
|
||||
0xe7db4ea6533afa9
|
||||
]))
|
||||
.is_err());
|
||||
|
||||
// r should not be in the field
|
||||
assert!(Fs::from_repr(Fs::char()).is_err());
|
||||
|
||||
// Multiply some arbitrary representations to see if the result is as expected.
|
||||
let a = FsRepr([0x5f2d0c05d0337b71, 0xa1df2b0f8a20479, 0xad73785e71bb863, 0x504a00480c9acec]);
|
||||
let a = FsRepr([
|
||||
0x5f2d0c05d0337b71,
|
||||
0xa1df2b0f8a20479,
|
||||
0xad73785e71bb863,
|
||||
0x504a00480c9acec,
|
||||
]);
|
||||
let mut a_fs = Fs::from_repr(a).unwrap();
|
||||
let b = FsRepr([0x66356ff51e477562, 0x60a92ab55cf7603, 0x8e4273c7364dd192, 0x36df8844a344dc5]);
|
||||
let b = FsRepr([
|
||||
0x66356ff51e477562,
|
||||
0x60a92ab55cf7603,
|
||||
0x8e4273c7364dd192,
|
||||
0x36df8844a344dc5,
|
||||
]);
|
||||
let b_fs = Fs::from_repr(b).unwrap();
|
||||
let c = FsRepr([0x7eef61708f4f2868, 0x747a7e6cf52946fb, 0x83dd75d7c9120017, 0x762f5177f0f3df7]);
|
||||
let c = FsRepr([
|
||||
0x7eef61708f4f2868,
|
||||
0x747a7e6cf52946fb,
|
||||
0x83dd75d7c9120017,
|
||||
0x762f5177f0f3df7,
|
||||
]);
|
||||
a_fs.mul_assign(&b_fs);
|
||||
assert_eq!(a_fs.into_repr(), c);
|
||||
|
||||
@@ -1222,15 +1529,39 @@ fn test_fs_from_into_repr() {
|
||||
#[test]
|
||||
fn test_fs_repr_display() {
|
||||
assert_eq!(
|
||||
format!("{}", FsRepr([0xa296db59787359df, 0x8d3e33077430d318, 0xd1abf5c606102eb7, 0xcbc33ee28108f0])),
|
||||
format!(
|
||||
"{}",
|
||||
FsRepr([
|
||||
0xa296db59787359df,
|
||||
0x8d3e33077430d318,
|
||||
0xd1abf5c606102eb7,
|
||||
0xcbc33ee28108f0
|
||||
])
|
||||
),
|
||||
"0x00cbc33ee28108f0d1abf5c606102eb78d3e33077430d318a296db59787359df".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", FsRepr([0x14cb03535054a620, 0x312aa2bf2d1dff52, 0x970fe98746ab9361, 0xc1e18acf82711e6])),
|
||||
format!(
|
||||
"{}",
|
||||
FsRepr([
|
||||
0x14cb03535054a620,
|
||||
0x312aa2bf2d1dff52,
|
||||
0x970fe98746ab9361,
|
||||
0xc1e18acf82711e6
|
||||
])
|
||||
),
|
||||
"0x0c1e18acf82711e6970fe98746ab9361312aa2bf2d1dff5214cb03535054a620".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", FsRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff])),
|
||||
format!(
|
||||
"{}",
|
||||
FsRepr([
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
])
|
||||
),
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -1242,11 +1573,29 @@ fn test_fs_repr_display() {
|
||||
#[test]
|
||||
fn test_fs_display() {
|
||||
assert_eq!(
|
||||
format!("{}", Fs::from_repr(FsRepr([0x5528efb9998a01a3, 0x5bd2add5cb357089, 0xc061fa6adb491f98, 0x70db9d143db03d9])).unwrap()),
|
||||
format!(
|
||||
"{}",
|
||||
Fs::from_repr(FsRepr([
|
||||
0x5528efb9998a01a3,
|
||||
0x5bd2add5cb357089,
|
||||
0xc061fa6adb491f98,
|
||||
0x70db9d143db03d9
|
||||
]))
|
||||
.unwrap()
|
||||
),
|
||||
"Fs(0x070db9d143db03d9c061fa6adb491f985bd2add5cb3570895528efb9998a01a3)".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", Fs::from_repr(FsRepr([0xd674745e2717999e, 0xbeb1f52d3e96f338, 0x9c7ae147549482b9, 0x999706024530d22])).unwrap()),
|
||||
format!(
|
||||
"{}",
|
||||
Fs::from_repr(FsRepr([
|
||||
0xd674745e2717999e,
|
||||
0xbeb1f52d3e96f338,
|
||||
0x9c7ae147549482b9,
|
||||
0x999706024530d22
|
||||
]))
|
||||
.unwrap()
|
||||
),
|
||||
"Fs(0x0999706024530d229c7ae147549482b9beb1f52d3e96f338d674745e2717999e)".to_string()
|
||||
);
|
||||
}
|
||||
@@ -1260,14 +1609,19 @@ fn test_fs_num_bits() {
|
||||
#[test]
|
||||
fn test_fs_root_of_unity() {
|
||||
assert_eq!(Fs::S, 1);
|
||||
assert_eq!(Fs::multiplicative_generator(), Fs::from_repr(FsRepr::from(6)).unwrap());
|
||||
assert_eq!(
|
||||
Fs::multiplicative_generator().pow([0x684b872f6b7b965b, 0x53341049e6640841, 0x83339d80809a1d80, 0x73eda753299d7d4]),
|
||||
Fs::multiplicative_generator(),
|
||||
Fs::from_repr(FsRepr::from(6)).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
Fs::multiplicative_generator().pow([
|
||||
0x684b872f6b7b965b,
|
||||
0x53341049e6640841,
|
||||
0x83339d80809a1d80,
|
||||
0x73eda753299d7d4
|
||||
]),
|
||||
Fs::root_of_unity()
|
||||
);
|
||||
assert_eq!(
|
||||
Fs::root_of_unity().pow([1 << Fs::S]),
|
||||
Fs::one()
|
||||
);
|
||||
assert_eq!(Fs::root_of_unity().pow([1 << Fs::S]), Fs::one());
|
||||
assert!(Fs::multiplicative_generator().sqrt().is_none());
|
||||
}
|
||||
|
Reference in New Issue
Block a user