Curve instantiation on base field
This commit is contained in:
parent
4b32ed6585
commit
ba73fdce48
|
@ -181,7 +181,12 @@ impl<'a, P: PrimeFieldParams> From<&'a str> for Fp<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: PrimeFieldParams> Clone for Fp<P> {
|
impl<P: PrimeFieldParams> Clone for Fp<P> {
|
||||||
fn clone(&self) -> Self { unimplemented!() }
|
fn clone(&self) -> Self {
|
||||||
|
Fp {
|
||||||
|
value: self.value.clone(),
|
||||||
|
_marker: PhantomData
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forward_ops_to_field_ops!(impl(P: PrimeFieldParams) Fp<P>);
|
forward_ops_to_field_ops!(impl(P: PrimeFieldParams) Fp<P>);
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#[macro_use]
|
||||||
|
mod macros;
|
||||||
|
|
||||||
pub mod fp;
|
pub mod fp;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -5,8 +8,9 @@ pub mod tests;
|
||||||
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use self::fp::{Fp, PrimeFieldParams};
|
use self::fp::{Fp, PrimeFieldParams};
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub trait Field: Sized + Clone {
|
pub trait Field: Sized + Clone + Debug {
|
||||||
fn zero() -> Self;
|
fn zero() -> Self;
|
||||||
fn one() -> Self;
|
fn one() -> Self;
|
||||||
fn random<R: Rng>(rng: &mut R) -> Self;
|
fn random<R: Rng>(rng: &mut R) -> Self;
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
macro_rules! forward_val_val_binop {
|
||||||
|
(impl($($t:ident: $p:ident),*) $imp:ident for $res:ty, $method:ident, $rhs:ty) => {
|
||||||
|
impl<$($t: $p),*> $imp<$rhs> for $res {
|
||||||
|
type Output = $res;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, other: $rhs) -> $res {
|
||||||
|
$imp::$method(&self, &other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_ref_val_binop {
|
||||||
|
(impl($($t:ident: $p:ident),*) $imp:ident for $res:ty, $method:ident, $rhs:ty) => {
|
||||||
|
impl<'a, $($t: $p),*> $imp<$rhs> for &'a $res {
|
||||||
|
type Output = $res;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, other: $rhs) -> $res {
|
||||||
|
$imp::$method(self, &other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_val_ref_binop {
|
||||||
|
(impl($($t:ident: $p:ident),*) $imp:ident for $res:ty, $method:ident, $rhs:ty) => {
|
||||||
|
impl<'a, $($t: $p),*> $imp<&'a $rhs> for $res {
|
||||||
|
type Output = $res;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, other: &$rhs) -> $res {
|
||||||
|
$imp::$method(&self, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_all_binop_to_ref_ref {
|
||||||
|
(impl($($t:ident: $p:ident),*) $imp:ident for $res:ty, $method:ident, $rhs:ty) => {
|
||||||
|
forward_val_val_binop!(impl($($t: $p),*) $imp for $res, $method, $rhs);
|
||||||
|
forward_ref_val_binop!(impl($($t: $p),*) $imp for $res, $method, $rhs);
|
||||||
|
forward_val_ref_binop!(impl($($t: $p),*) $imp for $res, $method, $rhs);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! forward_ops_to_group_ops {
|
||||||
|
(impl($($t:ident: $p:ident),*) $res:ty) => {
|
||||||
|
impl<'a, 'b, $($t: $p),*> Add<&'a $res> for &'b $res {
|
||||||
|
type Output = $res;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(self, other: &'a $res) -> $res {
|
||||||
|
Jacobian::add(self, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b, $($t: $p),*> Mul<&'a Fr> for &'b $res {
|
||||||
|
type Output = $res;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, other: &'a Fr) -> $res {
|
||||||
|
Jacobian::mul(self, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b, $($t: $p),*> Sub<&'a $res> for &'b $res {
|
||||||
|
type Output = $res;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, other: &'a $res) -> $res {
|
||||||
|
Jacobian::sub(self, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, $($t: $p),*> Neg for &'a $res {
|
||||||
|
type Output = $res;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn neg(self) -> $res {
|
||||||
|
Jacobian::neg(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$($t: $p),*> Neg for $res {
|
||||||
|
type Output = $res;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn neg(self) -> $res {
|
||||||
|
Jacobian::neg(&self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$($t: $p),*> PartialEq for $res {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
Jacobian::eq(self, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$($t: $p),*> Eq for $res {}
|
||||||
|
|
||||||
|
forward_all_binop_to_ref_ref!(impl($($t: $p),*) Add for $res, add, $res);
|
||||||
|
forward_all_binop_to_ref_ref!(impl($($t: $p),*) Sub for $res, sub, $res);
|
||||||
|
forward_all_binop_to_ref_ref!(impl($($t: $p),*) Mul for $res, mul, Fr);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,255 @@
|
||||||
|
use fields::Field;
|
||||||
|
use fields::fp::{PrimeFieldParams, Fp};
|
||||||
|
use super::Fr;
|
||||||
|
use rand::Rng;
|
||||||
|
use std::ops::{Add,Mul,Sub,Neg};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub mod tests;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod macros;
|
||||||
|
|
||||||
|
pub trait GroupParams: Sized {
|
||||||
|
type Base: Field;
|
||||||
|
|
||||||
|
fn zero() -> Jacobian<Self>;
|
||||||
|
fn one() -> Jacobian<Self>;
|
||||||
|
fn coeff_b() -> Self::Base;
|
||||||
|
fn name() -> &'static str;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Jacobian<P: GroupParams> {
|
||||||
|
x: P::Base,
|
||||||
|
y: P::Base,
|
||||||
|
z: P::Base
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: GroupParams> fmt::Debug for Jacobian<P> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}({:?}, {:?}, {:?})", P::name(), self.x, self.y, self.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: GroupParams> Clone for Jacobian<P> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Jacobian {
|
||||||
|
x: self.x.clone(),
|
||||||
|
y: self.y.clone(),
|
||||||
|
z: self.z.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub enum Affine<P: GroupParams> {
|
||||||
|
Zero,
|
||||||
|
Point{x: P::Base, y: P::Base}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: GroupParams> Clone for Affine<P> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
match *self {
|
||||||
|
Affine::Zero => Affine::Zero,
|
||||||
|
Affine::Point{ref x, ref y} => Affine::Point{x: x.clone(), y: y.clone()}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: GroupParams> Affine<P> {
|
||||||
|
/*
|
||||||
|
fn to_jacobian(self) -> Jacobian<P> {
|
||||||
|
match self {
|
||||||
|
Affine::Zero => P::zero(),
|
||||||
|
Affine::Point{x, y} => Jacobian {
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
z: P::Base::one()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: GroupParams> Jacobian<P> {
|
||||||
|
pub fn new(x: P::Base, y: P::Base, z: P::Base) -> Option<Self> {
|
||||||
|
let tmp = Jacobian {
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
z: z
|
||||||
|
};
|
||||||
|
|
||||||
|
if tmp.is_well_formed() {
|
||||||
|
Some(tmp)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn random<R: Rng>(rng: &mut R) -> Self {
|
||||||
|
Self::one() * &Fr::random(rng)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_well_formed(&self) -> bool {
|
||||||
|
if self.is_zero() {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
let x2 = self.x.squared();
|
||||||
|
let y2 = self.y.squared();
|
||||||
|
let z2 = self.z.squared();
|
||||||
|
|
||||||
|
let x3 = self.x.mul(&x2);
|
||||||
|
let z3 = self.z.mul(&z2);
|
||||||
|
let z6 = z3.squared();
|
||||||
|
|
||||||
|
(y2.eq(&z6.mul(&P::coeff_b()).add(&x3)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_affine(&self) -> Affine<P> {
|
||||||
|
if self.is_zero() {
|
||||||
|
Affine::Zero
|
||||||
|
} else {
|
||||||
|
let z_inv = self.z.inverse();
|
||||||
|
let z2_inv = z_inv.squared();
|
||||||
|
let z3_inv = z2_inv.mul(&z_inv);
|
||||||
|
|
||||||
|
Affine::Point {
|
||||||
|
x: self.x.mul(&z2_inv),
|
||||||
|
y: self.y.mul(&z3_inv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn zero() -> Self {
|
||||||
|
P::zero()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn one() -> Self {
|
||||||
|
P::one()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&self, other: &Self) -> Self {
|
||||||
|
if self.is_zero() {
|
||||||
|
return other.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
if other.is_zero() {
|
||||||
|
return self.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
let z1_squared = self.z.squared();
|
||||||
|
let z2_squared = other.z.squared();
|
||||||
|
let u1 = self.x.mul(&z2_squared);
|
||||||
|
let u2 = other.x.mul(&z1_squared);
|
||||||
|
let z1_cubed = self.z.mul(&z1_squared);
|
||||||
|
let z2_cubed = other.z.mul(&z2_squared);
|
||||||
|
let s1 = self.y.mul(&z2_cubed);
|
||||||
|
let s2 = other.y.mul(&z1_cubed);
|
||||||
|
|
||||||
|
if u1.eq(&u2) && s1.eq(&s2) {
|
||||||
|
self.double()
|
||||||
|
} else {
|
||||||
|
let h = u2.sub(&u1);
|
||||||
|
let s2_minus_s1 = s2.sub(&s1);
|
||||||
|
let i = h.add(&h).squared();
|
||||||
|
let j = h.mul(&i);
|
||||||
|
let r = s2_minus_s1.add(&s2_minus_s1);
|
||||||
|
let v = u1.mul(&i);
|
||||||
|
let s1_j = s1.mul(&j);
|
||||||
|
let x3 = r.squared().sub(&j).sub(&v.add(&v));
|
||||||
|
let y3 = r.mul(&v.sub(&x3)).sub(&s1_j.add(&s1_j));
|
||||||
|
|
||||||
|
Jacobian {
|
||||||
|
x: x3,
|
||||||
|
y: y3,
|
||||||
|
z: self.z.add(&other.z).squared().sub(&z1_squared).sub(&z2_squared).mul(&h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn double(&self) -> Self {
|
||||||
|
let a = self.x.squared();
|
||||||
|
let b = self.y.squared();
|
||||||
|
let c = b.squared();
|
||||||
|
let mut d = self.x.add(&b).squared().sub(&a).sub(&c);
|
||||||
|
d = d.add(&d);
|
||||||
|
let e = a.add(&a).add(&a);
|
||||||
|
let f = e.squared();
|
||||||
|
let x3 = f.sub(&d.add(&d));
|
||||||
|
let mut eight_c = c.add(&c);
|
||||||
|
eight_c = eight_c.add(&eight_c);
|
||||||
|
eight_c = eight_c.add(&eight_c);
|
||||||
|
let y3 = e.mul(&d.sub(&x3)).sub(&eight_c);
|
||||||
|
let y1z1 = self.y.mul(&self.z);
|
||||||
|
let z3 = y1z1.add(&y1z1);
|
||||||
|
|
||||||
|
Jacobian {
|
||||||
|
x: x3,
|
||||||
|
y: y3,
|
||||||
|
z: z3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eq(&self, other: &Self) -> bool {
|
||||||
|
if self.is_zero() {
|
||||||
|
return other.is_zero()
|
||||||
|
}
|
||||||
|
|
||||||
|
if other.is_zero() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let z1_squared = self.z.squared();
|
||||||
|
let z2_squared = other.z.squared();
|
||||||
|
|
||||||
|
if self.x.mul(&z2_squared).ne(&other.x.mul(&z1_squared)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let z1_cubed = self.z.mul(&z1_squared);
|
||||||
|
let z2_cubed = other.z.mul(&z2_squared);
|
||||||
|
|
||||||
|
if self.y.mul(&z2_cubed).ne(&other.y.mul(&z1_cubed)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn neg(&self) -> Self {
|
||||||
|
Jacobian {
|
||||||
|
x: self.x.clone(),
|
||||||
|
y: self.y.neg(),
|
||||||
|
z: self.z.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_zero(&self) -> bool {
|
||||||
|
self.z.is_zero()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mul<S: PrimeFieldParams>(&self, other: &Fp<S>) -> Jacobian<P> {
|
||||||
|
let mut result = Jacobian::<P>::zero();
|
||||||
|
let mut found_one = false;
|
||||||
|
for i in (0..S::bits()).rev() {
|
||||||
|
if found_one {
|
||||||
|
result = result.double();
|
||||||
|
}
|
||||||
|
|
||||||
|
if other.test_bit(i) {
|
||||||
|
found_one = true;
|
||||||
|
result = &result + self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn sub(&self, other: &Self) -> Jacobian<P> {
|
||||||
|
self.add(&other.neg())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_ops_to_group_ops!(impl(P: GroupParams) Jacobian<P>);
|
|
@ -0,0 +1,76 @@
|
||||||
|
use super::*;
|
||||||
|
use ::Fr;
|
||||||
|
use fields::Field;
|
||||||
|
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
|
pub fn group_trials<P: GroupParams>() {
|
||||||
|
fn test_doubling<P: GroupParams>() {
|
||||||
|
type G<P> = Jacobian<P>;
|
||||||
|
|
||||||
|
let one = G::<P>::one();
|
||||||
|
let two = one.add(&one);
|
||||||
|
let three = two.add(&one);
|
||||||
|
let four = three.add(&one);
|
||||||
|
|
||||||
|
assert_eq!(one.double(), two);
|
||||||
|
assert_eq!(two.double(), four);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn random_test_addition<P: GroupParams, R: Rng>(rng: &mut R) {
|
||||||
|
type G<P> = Jacobian<P>;
|
||||||
|
|
||||||
|
for _ in 0..50 {
|
||||||
|
let r1 = &G::<P>::random(rng);
|
||||||
|
let r2 = &G::<P>::random(rng);
|
||||||
|
let r3 = &G::<P>::random(rng);
|
||||||
|
|
||||||
|
let s1 = (r1 + r2) + r3;
|
||||||
|
let s2 = (r2 + r3) + r1;
|
||||||
|
|
||||||
|
assert_eq!(s1, s2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn random_test_doubling<P: GroupParams, R: Rng>(rng: &mut R) {
|
||||||
|
type G<P> = Jacobian<P>;
|
||||||
|
|
||||||
|
for _ in 0..50 {
|
||||||
|
let r1 = &G::<P>::random(rng);
|
||||||
|
let r2 = &G::<P>::random(rng);
|
||||||
|
|
||||||
|
let a = (r1 + r2) + r1;
|
||||||
|
let b = r1.double() + r2;
|
||||||
|
|
||||||
|
assert!(a.eq(&b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn random_test_dh<P: GroupParams, R: Rng>(rng: &mut R) {
|
||||||
|
type G<P> = Jacobian<P>;
|
||||||
|
|
||||||
|
for _ in 0..50 {
|
||||||
|
let alice_sk = Fr::random(rng);
|
||||||
|
let bob_sk = Fr::random(rng);
|
||||||
|
|
||||||
|
let alice_pk = G::<P>::one() * &alice_sk;
|
||||||
|
let bob_pk = G::<P>::one() * &bob_sk;
|
||||||
|
|
||||||
|
let alice_shared = &bob_pk * &alice_sk;
|
||||||
|
let bob_shared = &alice_pk * &bob_sk;
|
||||||
|
|
||||||
|
assert_eq!(alice_shared, bob_shared);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_doubling::<P>();
|
||||||
|
|
||||||
|
use rand::{SeedableRng,StdRng};
|
||||||
|
let seed: [usize; 4] = [103245, 191922, 1293, 192103];
|
||||||
|
let mut rng = StdRng::from_seed(&seed);
|
||||||
|
|
||||||
|
random_test_addition::<P, _>(&mut rng);
|
||||||
|
random_test_doubling::<P, _>(&mut rng);
|
||||||
|
random_test_dh::<P, _>(&mut rng);
|
||||||
|
}
|
||||||
|
|
15
src/lib.rs
15
src/lib.rs
|
@ -1,7 +1,18 @@
|
||||||
extern crate num;
|
extern crate num;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
mod macros;
|
|
||||||
mod fields;
|
mod fields;
|
||||||
mod params;
|
mod params;
|
||||||
|
|
||||||
|
mod groups;
|
||||||
|
|
||||||
|
pub use fields::fp::Fp;
|
||||||
|
pub use params::{FrParams,FqParams,G1Params};
|
||||||
|
pub use fields::Field;
|
||||||
|
pub use groups::Jacobian;
|
||||||
|
|
||||||
|
pub type Fr = Fp<FrParams>;
|
||||||
|
pub type Fq = Fp<FqParams>;
|
||||||
|
|
||||||
|
pub type Scalar = Fr;
|
||||||
|
pub type G1 = Jacobian<G1Params>;
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
use num::{Num,BigUint};
|
use num::{Num,BigUint};
|
||||||
|
use fields::Field;
|
||||||
use fields::fp::PrimeFieldParams;
|
use fields::fp::PrimeFieldParams;
|
||||||
|
use super::{Fr,Fq,G1};
|
||||||
|
use groups::*;
|
||||||
|
|
||||||
pub struct FrParams;
|
pub struct FrParams;
|
||||||
|
|
||||||
|
@ -25,12 +28,53 @@ impl PrimeFieldParams for FqParams {
|
||||||
fn test_fr() {
|
fn test_fr() {
|
||||||
use fields;
|
use fields;
|
||||||
|
|
||||||
fields::tests::field_trials::<fields::fp::Fp<FrParams>>();
|
fields::tests::field_trials::<super::Fr>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fq() {
|
fn test_fq() {
|
||||||
use fields;
|
use fields;
|
||||||
|
|
||||||
fields::tests::field_trials::<fields::fp::Fp<FqParams>>();
|
fields::tests::field_trials::<super::Fq>();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct G1Params;
|
||||||
|
|
||||||
|
impl GroupParams for G1Params {
|
||||||
|
type Base = super::Fq;
|
||||||
|
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"G1"
|
||||||
|
}
|
||||||
|
fn zero() -> Jacobian<Self> {
|
||||||
|
Jacobian::new(Fq::zero(), Fq::one(), Fq::zero()).unwrap()
|
||||||
|
}
|
||||||
|
fn one() -> Jacobian<Self> {
|
||||||
|
Jacobian::new(Fq::from("1"), Fq::from("2"), Fq::one()).unwrap()
|
||||||
|
}
|
||||||
|
fn coeff_b() -> Self::Base {
|
||||||
|
Fq::from("3")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_g1() {
|
||||||
|
use groups;
|
||||||
|
|
||||||
|
groups::tests::group_trials::<G1Params>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn g1_test_vector() {
|
||||||
|
let a = G1::one() * &Fr::from("19797905000333868150253315089095386158892526856493194078073564469188852136946");
|
||||||
|
let b = G1::one() * &Fr::from("2730506433347642574983433139433778984782882168213690554721050571242082865799");
|
||||||
|
let e = &a + &b;
|
||||||
|
|
||||||
|
let expect = G1::new(
|
||||||
|
Fq::from("18450621724990678172567114131642278789161361170999664461184794604011563728206"),
|
||||||
|
Fq::from("21329688341674583036384007811166435666174342925504675855816423131698588368496"),
|
||||||
|
Fq::one()
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
assert!(expect.eq(&e));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue