From a613ac846bcc79cec163a656cacafe653c034b3c Mon Sep 17 00:00:00 2001 From: jonch <9093549+jon-chuang@users.noreply.github.com> Date: Mon, 15 Mar 2021 21:07:09 +0800 Subject: [PATCH] hotfix --- Cargo.toml | 2 + ec/Cargo.toml | 3 +- ec/src/batch_verify.rs | 3 +- ec/src/models/short_weierstrass_jacobian.rs | 7 +- ec/src/models/twisted_edwards_extended.rs | 4 - ff/src/biginteger/macros.rs | 4 +- ff/src/fields/arithmetic.rs | 5 - ff/src/fields/mod.rs | 25 ++ scripts/glv-lattice-basis/Cargo.toml | 18 ++ scripts/glv-lattice-basis/LICENSE-APACHE | 201 +++++++++++++++ scripts/glv-lattice-basis/LICENSE-MIT | 19 ++ scripts/glv-lattice-basis/examples/main.rs | 12 + scripts/glv-lattice-basis/src/arithmetic.rs | 34 +++ scripts/glv-lattice-basis/src/lib.rs | 238 ++++++++++++++++++ scripts/to_dec_str.py | 14 ++ serialize/src/lib.rs | 1 + test-curves/Cargo.toml | 1 - test-curves/src/bls12_381/g1.rs | 6 +- test-curves/src/bn384_small_two_adicity/g1.rs | 5 + 19 files changed, 581 insertions(+), 21 deletions(-) create mode 100644 scripts/glv-lattice-basis/Cargo.toml create mode 100644 scripts/glv-lattice-basis/LICENSE-APACHE create mode 100644 scripts/glv-lattice-basis/LICENSE-MIT create mode 100644 scripts/glv-lattice-basis/examples/main.rs create mode 100644 scripts/glv-lattice-basis/src/arithmetic.rs create mode 100644 scripts/glv-lattice-basis/src/lib.rs create mode 100644 scripts/to_dec_str.py diff --git a/Cargo.toml b/Cargo.toml index b90f4199b..bcad6488d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,8 @@ members = [ "poly-benches", "test-curves", "test-templates", + + "scripts/glv-lattice-basis", ] [profile.release] diff --git a/ec/Cargo.toml b/ec/Cargo.toml index 6b643532e..9432e0e88 100644 --- a/ec/Cargo.toml +++ b/ec/Cargo.toml @@ -31,6 +31,7 @@ serde_json = { version = "1.0.58", optional = true } dirs = { version = "1.0.5", optional = true } log = { version = "0.4.11", optional = true } paste = "0.1" +zeroize = { version = "1", default-features = false, features = ["zeroize_derive"] } [dev-dependencies] rand_xorshift = "0.2" @@ -39,4 +40,4 @@ rand_xorshift = "0.2" cuda = [ "std", "parallel", "accel", "lazy_static", "serde_json", "dirs", "closure", "log" ] default = [] std = [ "ark-std/std", "ark-ff/std", "ark-serialize/std" ] -parallel = [ "std", "rayon", "ark-std/parallel", "rand/default" ] +parallel = [ "std", "rayon", "ark-std/parallel" ] diff --git a/ec/src/batch_verify.rs b/ec/src/batch_verify.rs index 2f81cf21b..ad4105edc 100644 --- a/ec/src/batch_verify.rs +++ b/ec/src/batch_verify.rs @@ -3,10 +3,9 @@ use crate::{ ProjectiveCurve, BATCH_AFFINE_BATCH_SIZE, }; use ark_ff::fields::FpParameters; -use ark_std::{cfg_chunks_mut, fmt, vec::Vec}; +use ark_std::{cfg_chunks_mut, fmt, vec::Vec, rand::Rng}; use num_traits::identities::Zero; -use rand::Rng; #[cfg(feature = "parallel")] use {rand::thread_rng, rayon::prelude::*}; diff --git a/ec/src/models/short_weierstrass_jacobian.rs b/ec/src/models/short_weierstrass_jacobian.rs index e5581c353..5f30a100b 100644 --- a/ec/src/models/short_weierstrass_jacobian.rs +++ b/ec/src/models/short_weierstrass_jacobian.rs @@ -1342,15 +1342,16 @@ impl ProjectiveCurve for GroupProjective

{ } } - fn mul::BigInt>>(mut self, other: S) -> Self { + fn mul>(mut self, other: S) -> Self { if P::has_glv() { let w = P::glv_window_size(); let mut res = Self::zero(); - impl_glv_mul!(Self, P, w, self, res, other); + let exponent_bigint = ::BigInt::from_slice(other.as_ref()); + impl_glv_mul!(Self, P, w, self, res, exponent_bigint); res } else { let mut res = Self::zero(); - for b in BitIteratorBE::without_leading_zeros(other.into()) { + for b in BitIteratorBE::without_leading_zeros(other.as_ref()) { res.double_in_place(); if b { res += self; diff --git a/ec/src/models/twisted_edwards_extended.rs b/ec/src/models/twisted_edwards_extended.rs index 70d911446..8922cc401 100644 --- a/ec/src/models/twisted_edwards_extended.rs +++ b/ec/src/models/twisted_edwards_extended.rs @@ -23,10 +23,6 @@ use ark_std::{ vec::Vec, }; use num_traits::{One, Zero}; -use rand::{ - distributions::{Distribution, Standard}, - Rng, -}; #[cfg(feature = "cuda")] use { crate::BatchGroupArithmeticSlice, accel::*, closure::closure, log::debug, peekmore::PeekMore, diff --git a/ff/src/biginteger/macros.rs b/ff/src/biginteger/macros.rs index c15436f3b..b71d2bfbc 100644 --- a/ff/src/biginteger/macros.rs +++ b/ff/src/biginteger/macros.rs @@ -288,7 +288,7 @@ macro_rules! bigint_impl { let mut carry = 0u64; for j in 0..$num_limbs / 2 { r[j + i] = - arithmetic::mac_with_carry(r[j + i], this[i], other[j], &mut carry); + mac_with_carry!(r[j + i], this[i], other[j], &mut carry); } r[$num_limbs / 2 + i] = carry; } @@ -305,7 +305,7 @@ macro_rules! bigint_impl { let mut carry = 0u64; for j in 0..($num_limbs - i) { r[j + i] = - arithmetic::mac_with_carry(r[j + i], this[i], other[j], &mut carry); + mac_with_carry!(r[j + i], this[i], other[j], &mut carry); } } Self::new(r) diff --git a/ff/src/fields/arithmetic.rs b/ff/src/fields/arithmetic.rs index 8b0245398..85e7977a6 100644 --- a/ff/src/fields/arithmetic.rs +++ b/ff/src/fields/arithmetic.rs @@ -249,11 +249,6 @@ macro_rules! impl_field_square_in_place { } } - // Checking the modulus at compile time - let first_bit_set = P::MODULUS.0[$limbs - 1] >> 63 != 0; - let mut all_bits_set = P::MODULUS.0[$limbs - 1] == !0 - (1 << 63); - for i in 1..$limbs { - all_bits_set &= P::MODULUS.0[$limbs - i - 1] == !0u64; #[cfg(use_asm)] #[allow(unsafe_code, unused_mut)] { diff --git a/ff/src/fields/mod.rs b/ff/src/fields/mod.rs index f7a1277ab..c66fc112d 100644 --- a/ff/src/fields/mod.rs +++ b/ff/src/fields/mod.rs @@ -67,6 +67,31 @@ macro_rules! field_new { }; } +#[macro_export] +macro_rules! field_new_from_raw_repr { + ($name:ident, $c0:expr) => { + $name { + 0: $c0, + 1: core::marker::PhantomData, + } + }; + ($name:ident, $c0:expr, $c1:expr $(,)?) => { + $name { + c0: $c0, + c1: $c1, + _parameters: core::marker::PhantomData, + } + }; + ($name:ident, $c0:expr, $c1:expr, $c2:expr $(,)?) => { + $name { + c0: $c0, + c1: $c1, + c2: $c2, + _parameters: core::marker::PhantomData, + } + }; +} + /// The interface for a generic field. pub trait Field: ToBytes diff --git a/scripts/glv-lattice-basis/Cargo.toml b/scripts/glv-lattice-basis/Cargo.toml new file mode 100644 index 000000000..aa4222e92 --- /dev/null +++ b/scripts/glv-lattice-basis/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "glv_lattice_basis" +version = "0.1.0" +authors = ["Jonathan Chuang"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ark-bls12-381 = { path = "../../../curves/bls12_381", features = ["curve"], default-features = false } +ark-ff = { path = "../../ff", default-features = false } +ark-ec = { path = "../../ec", default-features = false } +num-traits = { version = "0.2", default-features = false } +num-bigint = "0.4.0" + +[features] +default = [ "std" ] +std = [] diff --git a/scripts/glv-lattice-basis/LICENSE-APACHE b/scripts/glv-lattice-basis/LICENSE-APACHE new file mode 100644 index 000000000..16fe87b06 --- /dev/null +++ b/scripts/glv-lattice-basis/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/scripts/glv-lattice-basis/LICENSE-MIT b/scripts/glv-lattice-basis/LICENSE-MIT new file mode 100644 index 000000000..72dc60d84 --- /dev/null +++ b/scripts/glv-lattice-basis/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/scripts/glv-lattice-basis/examples/main.rs b/scripts/glv-lattice-basis/examples/main.rs new file mode 100644 index 000000000..30fc643f4 --- /dev/null +++ b/scripts/glv-lattice-basis/examples/main.rs @@ -0,0 +1,12 @@ +extern crate ark_bls12_381; + +use ark_bls12_381::G1Projective as GroupProjective; +use ark_ff::{ + BigInteger384 as BaseFieldBigInt, + BigInteger512 as FrWideBigInt, +}; +use glv_lattice_basis::*; + +fn main() { + print_glv_params::(); +} diff --git a/scripts/glv-lattice-basis/src/arithmetic.rs b/scripts/glv-lattice-basis/src/arithmetic.rs new file mode 100644 index 000000000..bf6cb9747 --- /dev/null +++ b/scripts/glv-lattice-basis/src/arithmetic.rs @@ -0,0 +1,34 @@ +use ark_ff::biginteger::BigInteger; + +// Naive long division +pub fn div_with_remainder( + numerator: BigInt, + divisor: BigInt, +) -> (BigInt, BigInt) { + assert!(divisor != BigInt::from(0), "Divisor cannot be zero"); + let mut remainder = numerator; + let mut quotient = BigInt::from(0); + + let div_num_bits = divisor.num_bits(); + + while remainder >= divisor { + let mut current_divisor = divisor; + let mut num_bits = 1 + remainder.num_bits() - div_num_bits; + current_divisor.muln(num_bits); + while current_divisor > remainder { + current_divisor.div2(); + num_bits -= 1; + } + remainder.sub_noborrow(¤t_divisor); + + let mut pow2_quot = BigInt::from(1); + pow2_quot.muln(num_bits); + quotient.add_nocarry(&pow2_quot); + } + + let mut reconstructed_numerator = + BigInt::mul_no_reduce_lo("ient.as_ref(), &divisor.as_ref()); + reconstructed_numerator.add_nocarry(&remainder); + assert_eq!(reconstructed_numerator, numerator); + (quotient, remainder) +} diff --git a/scripts/glv-lattice-basis/src/lib.rs b/scripts/glv-lattice-basis/src/lib.rs new file mode 100644 index 000000000..32ca76380 --- /dev/null +++ b/scripts/glv-lattice-basis/src/lib.rs @@ -0,0 +1,238 @@ +extern crate ark_ff; +extern crate ark_ec; +extern crate num_bigint; +extern crate num_traits; + +mod arithmetic; + +use num_bigint::BigUint; +use ark_ff::{BigInteger, Field, PrimeField}; +use ark_ec::ProjectiveCurve; +pub use arithmetic::*; +use num_traits::Zero; +use std::ops::Neg; + +/// Takes data from two endomorphisms and sorts out which corresponds to which +fn which_endo( + base_roots: (G::BaseField, G::BaseField), + scalar_roots: (G::ScalarField, G::ScalarField), +) -> ( + (G::BaseField, G::ScalarField), + (G::BaseField, G::ScalarField), +) { + // println!("{:?}, {:?}", base_roots, scalar_roots); + let g = G::prime_subgroup_generator(); + + let mut g_endo = g; + *g_endo.get_x() *= &base_roots.0; + + let d1 = if g.mul(scalar_roots.0.into_repr()) == g_endo { + (base_roots.0, scalar_roots.0) + } else { + let mut g_endo = g; + *g_endo.get_x() *= &base_roots.1; + assert!(g.mul(scalar_roots.0.into_repr()) == g_endo); + + (base_roots.1, scalar_roots.0) + }; + + let d2 = if g.mul(scalar_roots.1.into_repr()) == g_endo { + (base_roots.0, scalar_roots.1) + } else { + let mut g_endo = g; + *g_endo.get_x() *= &base_roots.1; + assert!(g.mul(scalar_roots.1.into_repr()) == g_endo); + + (base_roots.1, scalar_roots.1) + }; + + (d1, d2) +} + +fn cube_root_unity() -> (F, F) { + let char = B::from_slice(F::characteristic()); + let deg = F::extension_degree(); + let mut modulus = char; + for _ in 1..deg { + modulus = B::mul_no_reduce_lo(&modulus.as_ref(), &char.as_ref()); + } + + modulus.sub_noborrow(&B::from(1)); + let (q, r) = div_with_remainder(modulus, B::from(3)); + assert!(r == B::from(0)); + + let mut g = 2u32; + let mut root1 = F::one(); + loop { + if root1 != F::one() { + break; + } + let x = F::from(g); + root1 = x.pow(q); + g += 1; + } + let root2 = root1 * root1; + assert!(root1.pow(&[3]) == F::one()); + assert!(root2.pow(&[3]) == F::one()); + assert!(root1 != root2); + + (root1, root2) +} + +fn get_endo_data() -> (G::BaseField, G::ScalarField) { + which_endo::( + cube_root_unity::(), + cube_root_unity::::BigInt>(), + ) + .1 +} + +fn to_str(x: B) -> String { + BigUint::from_bytes_be(&x.to_bytes_be()[..]).to_string() +} + +pub fn print_glv_params() { + let (omega, lambda) = get_endo_data::(); + let g = G::prime_subgroup_generator(); + let mut g_endo = g; + *g_endo.get_x() *= ω + assert!(g.mul(lambda.into_repr()) == g_endo); + + println!("const OMEGA: Self::BaseField = {:?};", omega); + let n = ::modulus(); + println!("const LAMBDA: Self::ScalarField = {:?};", to_str(lambda.into_repr())); + + let vecs = get_lattice_basis::(n, lambda.into_repr()); + + // We check that `(|B1| + 2) * (|B2| + 2) < 2n` + // and `B_i^2 < 2n` e.g. `|B_i| < \sqrt{2n}$ + // We use this to prove some bounds later + let wide_modulus = WideBigInt::from_slice(&n.as_ref()[..]); + let two_modulus = WideBigInt::mul_no_reduce_lo( + &wide_modulus.as_ref()[..], + &WideBigInt::from(2).as_ref()[..], + ); + + let mut b1 = ((vecs.0).1).1; + let mut b2 = ((vecs.1).1).1; + let two = ::BigInt::from(2); + let b1b1 = WideBigInt::mul_no_reduce(&b1.as_ref()[..], &b1.as_ref()[..]); + let b2b2 = WideBigInt::mul_no_reduce(&b2.as_ref()[..], &b2.as_ref()[..]); + + b1.add_nocarry(&two); + b2.add_nocarry(&two); + let b1b2 = WideBigInt::mul_no_reduce(&b1.as_ref()[..], &b2.as_ref()[..]); + + assert!(b1b1 < two_modulus); + assert!(b2b2 < two_modulus); + assert!(b1b2 < two_modulus); + + for (i, vec) in [vecs.0, vecs.1].iter().enumerate() { + let (s1, (flag, t1)) = vec; + + let mut t1_big = WideBigInt::from_slice(t1.as_ref()); + let n_big = WideBigInt::from_slice(n.as_ref()); + t1_big.muln(::BigInt::NUM_LIMBS as u32 * 64); + let (g1_big, _) = div_with_remainder::(t1_big, n_big); + let g1 = ::BigInt::from_slice(g1_big.as_ref()); + + println!("/// |round(B{} * R / n)|", i + 1); + println!( + "const Q{}: ::BigInt = {:?};", + ((i + 1) % 2) + 1, + to_str(g1) + ); + println!( + "const B{}: ::BigInt = {:?};", + i + 1, + to_str(*t1) + ); + println!("const B{}_IS_NEG: bool = {:?};", i + 1, flag); + + debug_assert_eq!( + recompose_integer( + G::ScalarField::from_repr(*s1).unwrap(), + if !flag { + G::ScalarField::from_repr(*t1).unwrap() + } else { + G::ScalarField::from_repr(*t1).unwrap().neg() + }, + lambda + ), + G::ScalarField::zero() + ); + } + println!( + "const R_BITS: u32 = {:?};", + ::BigInt::NUM_LIMBS * 64 + ); +} + +// We work on arrays of size 3 +// We assume that |E(F_q)| < R = 2^{ceil(limbs/2) * 64} +pub fn get_lattice_basis( + n: F::BigInt, + lambda: F::BigInt, +) -> ( + (F::BigInt, (bool, F::BigInt)), + (F::BigInt, (bool, F::BigInt)), +) { + let mut r = [n, lambda, n]; + let one = F::one(); + let zero = F::zero(); + let mut t: [F; 3] = [zero, one, zero]; + let max_num_bits_lattice = (F::BigInt::from_slice(F::characteristic()).num_bits() - 1) / 2 + 1; + + // We can use an approximation as we are merely using a heuristic. We should + // check that the parameters obtained from this heuristic satisfies the + // required conditions separately. + let sqrt_n = as_f64(n.as_ref()).sqrt(); + + // println!("Log sqrtn: {}", sqrt_n.log2()); + + let mut i = 0; + // While r_i >= sqrt(n), we perform the extended euclidean algorithm so that + // si*n + ti*lambda = ri then return the vectors (r_i, (sign(t_i), |t_i|)), + // (r_i+1, (sign(t_i+1), |t_i+1|)) Notice this makes ri + (-ti)*lambda = 0 + // mod n, which is what we desire for our short lattice basis + while as_f64(r[(i + 1) % 3].as_ref()) >= sqrt_n { + // while i < 20 { + let (q, rem): (F::BigInt, F::BigInt) = + div_with_remainder::(r[i % 3], r[(i + 1) % 3]); + r[(i + 2) % 3] = rem; + let int_q = F::from_repr(q).unwrap(); + t[(i + 2) % 3] = t[i % 3] - int_q * (t[(i + 1) % 3]); + + i += 1; + } + let just_computed = (i + 1) % 3; + // We reverse the signs due to s_i*n = r_i - t_i*LAMBDA + let (neg_flag1, t1) = if t[just_computed].into_repr().num_bits() <= max_num_bits_lattice { + (true, t[just_computed].into_repr()) + } else { + (false, t[just_computed].neg().into_repr()) + }; + let vec_1 = (r[just_computed], (neg_flag1, t1)); + + let prev = i % 3; + let (neg_flag2, t2) = if t[prev].into_repr().num_bits() <= max_num_bits_lattice { + (true, t[prev].into_repr()) + } else { + (false, t[prev].neg().into_repr()) + }; + let vec_2 = (r[prev], (neg_flag2, t2)); + + (vec_1, vec_2) +} + +pub fn recompose_integer(k1: F, k2: F, lambda: F) -> F { + k1 + &(k2 * &lambda) +} + +fn as_f64(bigint_ref: &[u64]) -> f64 { + let mut n_float: f64 = 0.0; + for (i, limb) in bigint_ref.iter().enumerate() { + n_float += (*limb as f64) * 2f64.powf((i as f64) * 64f64) + } + n_float +} diff --git a/scripts/to_dec_str.py b/scripts/to_dec_str.py new file mode 100644 index 000000000..828b4057e --- /dev/null +++ b/scripts/to_dec_str.py @@ -0,0 +1,14 @@ +def from_u64_slice_to_decimal_str(x): + ret = 0 + for i, limb in enumerate(x): + print(i) + print(ret) + ret += 2 ** (i*64) * limb + return ret + +print(from_u64_slice_to_decimal_str([ + 7865245318337523249, + 18346590209729131401, + 15545362854776399464, + 6505881510324251116, +])) diff --git a/serialize/src/lib.rs b/serialize/src/lib.rs index 06cd06b53..3b5db4fcc 100644 --- a/serialize/src/lib.rs +++ b/serialize/src/lib.rs @@ -12,6 +12,7 @@ use ark_std::{ rc::Rc, string::String, vec::Vec, + vec, }; pub use error::*; pub use flags::*; diff --git a/test-curves/Cargo.toml b/test-curves/Cargo.toml index c70914f6d..da48978d6 100644 --- a/test-curves/Cargo.toml +++ b/test-curves/Cargo.toml @@ -13,7 +13,6 @@ paste = "0.1" ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false } ark-ff = { path = "../ff", default-features = false } ark-ec = { path = "../ec", default-features = false } -ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false } lazy_static = { version = "1.4.0", optional = true } diff --git a/test-curves/src/bls12_381/g1.rs b/test-curves/src/bls12_381/g1.rs index 5653bc02d..64fabeec3 100644 --- a/test-curves/src/bls12_381/g1.rs +++ b/test-curves/src/bls12_381/g1.rs @@ -7,7 +7,7 @@ use ark_ec::{ }; use ark_ff::{ biginteger::{BigInteger256, BigInteger384, BigInteger512}, - field_new, PrimeField, Zero, + field_new, field_new_from_raw_repr, PrimeField, Zero, }; pub type G1Affine = GroupAffine; @@ -25,7 +25,7 @@ impl_scalar_mul_kernel_glv!(bls12_381, "ark-bls12-381", g1, G1Projective); impl GLVParameters for Parameters { type WideBigInt = BigInteger512; - const OMEGA: Self::BaseField = field_new!( + const OMEGA: Self::BaseField = field_new_from_raw_repr!( Fq, BigInteger384([ 3526659474838938856, @@ -36,7 +36,7 @@ impl GLVParameters for Parameters { 368068849512964448, ]) ); - const LAMBDA: Self::ScalarField = field_new!( + const LAMBDA: Self::ScalarField = field_new_from_raw_repr!( Fr, BigInteger256([ 7865245318337523249, diff --git a/test-curves/src/bn384_small_two_adicity/g1.rs b/test-curves/src/bn384_small_two_adicity/g1.rs index aadf08151..27fc71349 100644 --- a/test-curves/src/bn384_small_two_adicity/g1.rs +++ b/test-curves/src/bn384_small_two_adicity/g1.rs @@ -1,4 +1,5 @@ use ark_ec::{ + impl_glv_for_sw, impl_scalar_mul_kernel, impl_scalar_mul_parameters, models::{ModelParameters, SWModelParameters}, short_weierstrass_jacobian::*, }; @@ -12,6 +13,8 @@ pub type G1Projective = GroupProjective; #[derive(Clone, Default, PartialEq, Eq)] pub struct Parameters; +impl_scalar_mul_kernel!(bn384, "ark-bn384", g1, G1Projective); + impl ModelParameters for Parameters { type BaseField = Fq; type ScalarField = Fr; @@ -38,6 +41,8 @@ impl SWModelParameters for Parameters { fn mul_by_a(_: &Self::BaseField) -> Self::BaseField { Self::BaseField::zero() } + + impl_scalar_mul_parameters!(G1Projective); } /// G1_GENERATOR_X = -1