use crate::digits::util::unsafe_convert_bytes_to_limbs_mut;
extern crate num_traits;
#[cfg(test)]
extern crate rand;
#[cfg(test)]
#[macro_use]
extern crate proptest;
#[macro_use]
pub mod digits {
#[macro_use]
pub mod ff31;
pub mod constant_bool;
pub mod constant_time_primitives;
pub mod util;
}
fp31!(
fp_480,
Fp480,
480,
16,
[
1055483031, 1386897616, 898494285, 1391857335, 488544832, 1799384686, 193115992, 565079768,
190358044, 1260077487, 1583277252, 222489098, 760385720, 330553579, 429458313, 32766
],
[
867470981, 808770461, 73326154, 873519719, 731426156, 154316581, 1066899290, 1406793571,
1662108208, 231227174, 1893732143, 1300610845, 325218135, 866248622, 1596183093,
1288991726, 65539
],
[
172371756, 1046460578, 1674812214, 732914258, 1831602581, 1542423573, 2092897579,
735180796, 1991677061, 919723849, 802444109, 1677449578, 1892606677, 1820724059,
1324905779, 16249
],
[
197589901, 1933752831, 580428568, 527417626, 249573438, 264164054, 609560334, 32358085,
944568904, 1556682934, 1807973447, 1881920392, 10254137, 588677610, 1214264513, 6960
],
1345299673
);
fp31!(
fp_256,
Fp256,
256,
9,
[
1577621095, 817453272, 47634040, 1927038601, 407749150, 1308464908, 685899370, 1518399909,
143
],
[
618474456, 1306750627, 1454330209, 2032300189, 1138536719, 1905629153, 1016481908,
1139000707, 1048853973, 14943480
],
[
1126407027, 1409097648, 718270744, 92148126, 1120340506, 1733383256, 1472506103,
1994474164, 90
],
[
1687342104, 733402836, 182672516, 801641709, 2122695487, 1290522951, 66525586, 319877849,
59
],
2132269737
);
impl From<[u8; 64]> for fp_256::Fp256 {
fn from(src: [u8; 64]) -> Self {
let mut limbs = [0u32; 18];
unsafe_convert_bytes_to_limbs_mut(&src, &mut limbs, 64);
fp_256::Fp256::new(fp_256::Fp256::reduce_barrett(&limbs))
}
}
impl From<[u8; 64]> for fp_256::Monty {
fn from(src: [u8; 64]) -> Self {
let mut limbs = [0u32; 18];
unsafe_convert_bytes_to_limbs_mut(&src, &mut limbs, 64);
fp_256::Fp256::new(fp_256::Fp256::reduce_barrett(&limbs)).to_monty()
}
}
impl From<[u8; 64]> for fp_480::Fp480 {
fn from(src: [u8; 64]) -> Self {
let mut limbs = [0u32; 32];
unsafe_convert_bytes_to_limbs_mut(&src, &mut limbs, 64);
fp_480::Fp480::new(fp_480::Fp480::reduce_barrett(&limbs))
}
}
pub fn from_sixty_four_bytes(src: [u8; 64]) -> [u32; 17] {
let mut limbs = [0u32; 17];
unsafe_convert_bytes_to_limbs_mut(&src, &mut limbs, 64);
limbs
}
#[cfg(test)]
mod lib {
use super::*;
use num_traits::{One, Zero};
#[test]
fn mont_mult1() {
let a = fp_480::Fp480::new([1u32; fp_480::NUMLIMBS]);
let expected = fp_480::Fp480::new([
116566737, 258320304, 899113910, 662693571, 1878328939, 137325967, 973027057,
1096098811, 1800707178, 257433595, 567863213, 586185298, 1453955551, 666215613,
1815208656, 2158,
]);
assert_eq!((a.to_monty() * a.to_monty()).to_norm(), expected);
}
#[test]
fn mont_mult2() {
let a = fp_256::Fp256::new([1u32; fp_256::NUMLIMBS]);
let expected = fp_256::Fp256::new([
1001314762, 222542809, 1966841077, 1532144542, 1509311353, 1324885496, 689426205,
1636449281, 61,
]);
assert_eq!(a.to_monty().limbs, expected.limbs);
}
#[test]
fn static_add_31_bit() {
let expected = fp_256::Fp256::new([
1687077409, 1547669063, 1685320481, 1036948901, 4206667, 1832642533, 59073627,
1086014588, 91,
]);
let a = fp_256::Fp256::new([
558607428, 108819344, 866477261, 408251927, 1279719733, 496811896, 1446228323,
1302207248, 117,
]);
assert_eq!(a + a, expected);
}
#[test]
fn static_div_31_bit() {
let result = fp_256::Fp256::new([
788810548, 408726636, 1097558844, 963519300, 203874575, 654232454, 1416691509,
1832941778, 71,
]);
let b = fp_256::Fp256::new([
1687077409, 1547669063, 1685320481, 1036948901, 4206667, 1832642533, 59073627,
1086014588, 91,
]);
let a = fp_256::Fp256::new([
558607428, 108819344, 866477261, 408251927, 1279719733, 496811896, 1446228323,
1302207248, 117,
]);
assert_eq!(a / b, result);
assert_eq!(result * b, a);
}
#[test]
fn static_co_reduce_256_bit() {
let a_result = [
2102762755, 340721811, 1526670465, 1233221938, 1621045422, 3878, 0, 0, 0,
];
let b_result = [
496048871, 1583721686, 351053136, 72635571, 14163922, 1245, 0, 0, 0,
];
let mut a = [
2003540029, 1136642599, 2013451521, 1081750855, 2108178975, 1491192821, 4, 0, 0,
];
let mut b = [
2089475485, 1450247307, 1692152066, 1263335112, 856386648, 2075289019, 25, 0, 0,
];
let pa = 6648347;
let pb = -1201787;
let qa = -12242368;
let qb = 2213312;
fp_256::Fp256::co_reduce(&mut a, &mut b, pa, pb, qa, qb);
assert_eq!(a, a_result);
assert_eq!(b, b_result);
}
#[test]
fn fp_256_31_normalize_prime_minus_1() {
let a = fp_256::Fp256::new([
1577621094, 817453272, 47634040, 1927038601, 407749150, 1308464908, 685899370,
1518399909, 143,
]);
let result = a.normalize_little();
assert_eq!(a, result);
}
#[test]
fn fp_256_31_normalize_prime_plus_1() {
let a = fp_256::Fp256::new([
1577621096, 817453272, 47634040, 1927038601, 407749150, 1308464908, 685899370,
1518399909, 143,
]);
let result = a.normalize_little();
assert_eq!(result, fp_256::Fp256::one());
}
#[test]
fn hex_dec_print() {
let p = fp_480::Fp480::new(fp_480::PRIME);
assert_eq!(p.to_str_hex().as_str(), "fffc66640e249d9ec75ad5290b81a85d415797b931258da0d78b58a21c435cddb02e0add635a037371d1e9a40a5ec1d6ed637bd3695530683ee96497");
let p = fp_256::Fp256::new(fp_256::PRIME);
assert_eq!(
p.to_str_hex().as_str(),
"8fb501e34aa387f9aa6fecb86184dc21ee5b88d120b5b59e185cac6c5e089667"
);
}
#[test]
fn zero1() {
let a = fp_480::Fp480::new([1u32; fp_480::NUMLIMBS]);
assert_eq!(a - a, fp_480::Fp480::zero());
assert_eq!(a + fp_480::Fp480::zero(), a);
assert_eq!(a * fp_480::Fp480::zero(), fp_480::Fp480::zero());
}
#[test]
fn mul_precalc() {
let a = fp_480::Fp480::new([1u32; fp_480::NUMLIMBS]);
let expected = fp_480::Fp480::new([
116566737, 258320304, 899113910, 662693571, 1878328939, 137325967, 973027057,
1096098811, 1800707178, 257433595, 567863213, 586185298, 1453955551, 666215613,
1815208656, 2158,
]);
assert_eq!(a * a, expected);
}
#[test]
fn barrett_reduction() {
let yuuuuge = [
1717850385, 975992930, 1085120981, 290253968, 541414174, 1010009590, 992858995,
1544978906, 479141764, 595912303, 1182831228, 1732726309, 208474352, 431120126,
1041596558, 2047733944, 736903860, 964324177, 245966458, 1453527551, 1075327941,
2050995692, 1443163149, 1018800365, 275337413, 1465124270, 409168091, 1829798574,
231461389, 574854543, 1073623861, 0,
];
assert_eq!(fp_480::Fp480::reduce_barrett(&yuuuuge), [0u32; 16]);
let max = [
1657593201, 1540832074, 1649487609, 580760650, 1029551730, 2022468362, 1718453138,
429469137, 2035023273, 199629839, 1710284256, 907874956, 1233314842, 1123865686,
1935834002, 1544277094, 20651, 0,
];
assert_eq!(fp_256::Fp256::reduce_barrett(&max), [0u32; 9]);
let twop = [
2110966062, 626311584, 1796988571, 636231022, 977089665, 1451285724, 386231985,
1130159536, 380716088, 372671326, 1019070857, 444978197, 1520771440, 661107158,
858916626, 65532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
assert_eq!(fp_480::Fp480::reduce_barrett(&twop), [0u32; 16]);
let xsquared = [
1256476377, 2102446331, 1632594058, 1382086562, 1977188283, 1189833019, 98505500,
386297644, 482637868, 751487015, 968545410, 1465590326, 1636829572, 1068997602,
2112274040, 675780054, 69810239, 774249708, 1799903083, 2117638065, 492942939,
1246496911, 1605644669, 704647290, 1852334453, 1325788175, 178848546, 1997374434,
1793336617, 22325931, 160731937, 0,
];
let expected = [
869156423, 665057899, 1391192655, 894967811, 1796343620, 436717649, 1265537281,
727485642, 573430722, 980187994, 1374252810, 1447922940, 438926278, 1658380520,
1097281981, 18991,
];
assert_eq!(fp_480::Fp480::reduce_barrett(&xsquared), expected);
}
#[test]
fn debug_hex_output_test256() {
let other = fp_256::Fp256::new([0, 0, 0x00FFFFFFFFu32, 0, 0, 0, 0, 0, 0]);
let str = format!("hex: {:x}", other);
assert_eq!(
&str.replace(" ", ""),
"hex:0x00000000000000000000000000000000000000003fffffffc000000000000000"
);
let other = fp_256::Fp256::new([0x7FFFFFFF; 9]);
let str = format!("hex: {:x}", other);
assert_eq!(
&str.replace(" ", ""),
"hex:0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
}
#[test]
fn neg_test256() {
let a = fp_256::Fp256::one();
let b = fp_256::Fp256::new([
136300585, 707444127, 807555021, 1811877557, 2098044538, 317321736, 1206406714, 25, 0,
]);
assert_eq!(a * b, b);
assert_eq!(-a * b, -b);
}
#[test]
fn test_from_sha_static() {
let x = [1u8; 64];
let expected = fp_256::Fp256::new([
943682914, 296735281, 102601666, 655105971, 441508414, 1938904809, 1433209327,
308023271, 117,
]);
assert_eq!(fp_256::Fp256::from(x), expected);
let mut x = [0u8; 64];
x[16..32].iter_mut().for_each(|i| *i = 1);
x[48..64].iter_mut().for_each(|i| *i = 1);
let expected = fp_256::Fp256::new([
967511966, 1307044956, 1229633257, 566771625, 922104236, 1401873859, 1287751493,
1191577462, 120,
]);
assert_eq!(fp_256::Fp256::from(x), expected);
}
#[test]
fn fp256_to_bytes_known_good_value() {
use crate::fp_256::Fp256;
let fp = Fp256::from(255u32);
let bytes = fp.to_bytes_array();
let expected_result = {
let mut array = [0u8; 32];
array[31] = 255;
array
};
assert_eq!(bytes, expected_result);
}
#[test]
fn fp256_from_bytes_should_mod() {
use crate::fp_256::Fp256;
let max_bytes = Fp256::from([255u8; 32]);
let expected_result = Fp256::new([
569862552, 1330030375, 2099849607, 220445046, 1739734497, 839018739, 1461584277,
629083738, 112,
]);
assert_eq!(max_bytes, expected_result);
let to_bytes_result = max_bytes.to_bytes_array();
assert_eq!(
to_bytes_result,
[
112, 74, 254, 28, 181, 92, 120, 6, 85, 144, 19, 71, 158, 123, 35, 222, 17, 164,
119, 46, 223, 74, 74, 97, 231, 163, 83, 147, 161, 247, 105, 152
]
);
}
}