All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ethereum.crypto.zksnark.Fp2 Maven / Gradle / Ivy

Go to download

Java implementation of the Ethereum protocol adapted to use for Hedera Smart Contract Service

The newest version!
/*
 * Copyright (c) [2016] [  ]
 * This file is part of the ethereumJ library.
 *
 * The ethereumJ library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The ethereumJ library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the ethereumJ library. If not, see .
 */
package org.ethereum.crypto.zksnark;

import java.math.BigInteger;

/**
 * Arithmetic in F_p2 
*
* * "p" equals 21888242871839275222246405745257275088696311157297823662689037894645226208583, * elements of F_p2 are represented as a polynomials "a * i + b" modulo "i^2 + 1" from the ring F_p[i]
*
* * Field arithmetic is ported from libff
* * @author Mikhail Kalinin * @since 01.09.2017 */ class Fp2 implements Field { static final Fp2 ZERO = new Fp2(Fp.ZERO, Fp.ZERO); static final Fp2 _1 = new Fp2(Fp._1, Fp.ZERO); static final Fp2 NON_RESIDUE = new Fp2(BigInteger.valueOf(9), BigInteger.ONE); static final Fp[] FROBENIUS_COEFFS_B = new Fp[] { new Fp(BigInteger.ONE), new Fp(new BigInteger("21888242871839275222246405745257275088696311157297823662689037894645226208582")) }; Fp a; Fp b; Fp2(Fp a, Fp b) { this.a = a; this.b = b; } Fp2(BigInteger a, BigInteger b) { this(new Fp(a), new Fp(b)); } @Override public Fp2 squared() { // using Complex squaring Fp ab = a.mul(b); Fp ra = a.add(b).mul(b.mul(Fp.NON_RESIDUE).add(a)) .sub(ab).sub(ab.mul(Fp.NON_RESIDUE)); // ra = (a + b)(a + NON_RESIDUE * b) - ab - NON_RESIDUE * b Fp rb = ab.dbl(); return new Fp2(ra, rb); } @Override public Fp2 mul(Fp2 o) { Fp aa = a.mul(o.a); Fp bb = b.mul(o.b); Fp ra = bb.mul(Fp.NON_RESIDUE).add(aa); // ra = a1 * a2 + NON_RESIDUE * b1 * b2 Fp rb = a.add(b).mul(o.a.add(o.b)).sub(aa).sub(bb); // rb = (a1 + b1)(a2 + b2) - a1 * a2 - b1 * b2 return new Fp2(ra, rb); } @Override public Fp2 add(Fp2 o) { return new Fp2(a.add(o.a), b.add(o.b)); } @Override public Fp2 sub(Fp2 o) { return new Fp2(a.sub(o.a), b.sub(o.b)); } @Override public Fp2 dbl() { return this.add(this); } @Override public Fp2 inverse() { Fp t0 = a.squared(); Fp t1 = b.squared(); Fp t2 = t0.sub(Fp.NON_RESIDUE.mul(t1)); Fp t3 = t2.inverse(); Fp ra = a.mul(t3); // ra = a * t3 Fp rb = b.mul(t3).negate(); // rb = -(b * t3) return new Fp2(ra, rb); } @Override public Fp2 negate() { return new Fp2(a.negate(), b.negate()); } @Override public boolean isZero() { return this.equals(ZERO); } @Override public boolean isValid() { return a.isValid() && b.isValid(); } static Fp2 create(BigInteger aa, BigInteger bb) { Fp a = Fp.create(aa); Fp b = Fp.create(bb); return new Fp2(a, b); } static Fp2 create(byte[] aa, byte[] bb) { Fp a = Fp.create(aa); Fp b = Fp.create(bb); return new Fp2(a, b); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Fp2 fp2 = (Fp2) o; if (a != null ? !a.equals(fp2.a) : fp2.a != null) return false; return !(b != null ? !b.equals(fp2.b) : fp2.b != null); } Fp2 frobeniusMap(int power) { Fp ra = a; Fp rb = FROBENIUS_COEFFS_B[power % 2].mul(b); return new Fp2(ra, rb); } Fp2 mulByNonResidue() { return NON_RESIDUE.mul(this); } @Override public String toString() { return String.format("%si + %s", a.toString(), b.toString()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy