Coverage Summary for Class: Fp2 (co.rsk.crypto.altbn128java)

Class Class, % Method, % Line, %
Fp2 0% (0/1) 0% (0/21) 0% (0/50)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2019 RSK Labs Ltd. 4  * (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>) 5  * 6  * This program is free software: you can redistribute it and/or modify 7  * it under the terms of the GNU Lesser General Public License as published by 8  * the Free Software Foundation, either version 3 of the License, or 9  * (at your option) any later version. 10  * 11  * This program is distributed in the hope that it will be useful, 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14  * GNU Lesser General Public License for more details. 15  * 16  * You should have received a copy of the GNU Lesser General Public License 17  * along with this program. If not, see <http://www.gnu.org/licenses/>. 18  */ 19  20 package co.rsk.crypto.altbn128java; 21  22 import java.math.BigInteger; 23 import java.util.Objects; 24  25 /** 26  * Arithmetic in F_p2 <br/> 27  * <br/> 28  * 29  * "p" equals 21888242871839275222246405745257275088696311157297823662689037894645226208583, 30  * elements of F_p2 are represented as a polynomials "a * i + b" modulo "i^2 + 1" from the ring F_p[i] <br/> 31  * <br/> 32  * 33  * Field arithmetic is ported from <a href="https://github.com/scipr-lab/libff/blob/master/libff/algebra/fields/fp2.tcc">libff</a> <br/> 34  * 35  * @author Mikhail Kalinin 36  * @since 01.09.2017 37  */ 38 class Fp2 implements Field<Fp2> { 39  40  public static final Fp2 ZERO = new Fp2(Fp.ZERO, Fp.ZERO); 41  public static final Fp2 _1 = new Fp2(Fp._1, Fp.ZERO); 42  public static final Fp2 NON_RESIDUE = new Fp2(BigInteger.valueOf(9), BigInteger.ONE); 43  44  private Fp a; 45  private Fp b; 46  47  private static final Fp[] FROBENIUS_COEFFS_B = new Fp[] { 48  new Fp(BigInteger.ONE), 49  new Fp(new BigInteger("21888242871839275222246405745257275088696311157297823662689037894645226208582")) 50  }; 51  52  53  public Fp a() { 54  return a; 55  } 56  57  public Fp b() { 58  return b; 59  } 60  61  Fp2(Fp a, Fp b) { 62  this.a = a; 63  this.b = b; 64  } 65  66  Fp2(BigInteger a, BigInteger b) { 67  this(new Fp(a), new Fp(b)); 68  } 69  70  @Override 71  public Fp2 squared() { 72  73  // using Complex squaring 74  75  Fp ab = a.mul(b); 76  77  Fp ra = a.add(b).mul(b.mul(Fp.NON_RESIDUE).add(a)) 78  .sub(ab).sub(ab.mul(Fp.NON_RESIDUE)); // ra = (a + b)(a + NON_RESIDUE * b) - ab - NON_RESIDUE * b 79  Fp rb = ab.dbl(); 80  81  return new Fp2(ra, rb); 82  } 83  84  @Override 85  public Fp2 mul(Fp2 o) { 86  87  Fp aa = a.mul(o.a); 88  Fp bb = b.mul(o.b); 89  90  Fp ra = bb.mul(Fp.NON_RESIDUE).add(aa); // ra = a1 * a2 + NON_RESIDUE * b1 * b2 91  Fp rb = a.add(b).mul(o.a.add(o.b)).sub(aa).sub(bb); // rb = (a1 + b1)(a2 + b2) - a1 * a2 - b1 * b2 92  93  return new Fp2(ra, rb); 94  } 95  96  @Override 97  public Fp2 add(Fp2 o) { 98  return new Fp2(a.add(o.a), b.add(o.b)); 99  } 100  101  @Override 102  public Fp2 sub(Fp2 o) { 103  return new Fp2(a.sub(o.a), b.sub(o.b)); 104  } 105  106  @Override 107  public Fp2 dbl() { 108  return this.add(this); 109  } 110  111  @Override 112  public Fp2 inverse() { 113  114  Fp t0 = a.squared(); 115  Fp t1 = b.squared(); 116  Fp t2 = t0.sub(Fp.NON_RESIDUE.mul(t1)); 117  Fp t3 = t2.inverse(); 118  119  Fp ra = a.mul(t3); // ra = a * t3 120  Fp rb = b.mul(t3).negate(); // rb = -(b * t3) 121  122  return new Fp2(ra, rb); 123  } 124  125  @Override 126  public Fp2 negate() { 127  return new Fp2(a.negate(), b.negate()); 128  } 129  130  @Override 131  public boolean isZero() { 132  return this.equals(ZERO); 133  } 134  135  @Override 136  public boolean isValid() { 137  return a.isValid() && b.isValid(); 138  } 139  140  static Fp2 create(BigInteger aa, BigInteger bb) { 141  142  Fp a = Fp.create(aa); 143  Fp b = Fp.create(bb); 144  145  return new Fp2(a, b); 146  } 147  148  static Fp2 create(byte[] aa, byte[] bb) { 149  150  Fp a = Fp.create(aa); 151  Fp b = Fp.create(bb); 152  153  return new Fp2(a, b); 154  } 155  156  @Override 157  public boolean equals(Object o) { 158  if (this == o) {return true;} 159  if (o == null || getClass() != o.getClass()) {return false;} 160  161  Fp2 fp2 = (Fp2) o; 162  163  if (a != null ? !a.equals(fp2.a) : fp2.a != null) {return false;} 164  return !(b != null ? !b.equals(fp2.b) : fp2.b != null); 165  166  } 167  168  @Override 169  public int hashCode() { 170  return Objects.hash(a,b); 171  } 172  173  Fp2 frobeniusMap(int power) { 174  175  Fp ra = a; 176  Fp rb = FROBENIUS_COEFFS_B[power % 2].mul(b); 177  178  return new Fp2(ra, rb); 179  } 180  181  Fp2 mulByNonResidue() { 182  return NON_RESIDUE.mul(this); 183  } 184  185  @Override 186  public String toString() { 187  return String.format("%si + %s", a.toString(), b.toString()); 188  } 189 }