Path: blob/master/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/Ed448Operations.java
41162 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package sun.security.ec.ed;2526import sun.security.ec.point.*;27import sun.security.util.math.*;2829import java.math.BigInteger;30import java.util.function.Function;3132// Arithmetic works for a=1 and non-square d33/*34* Elliptic curve point arithmetic, decoding, and other operations for the35* family of curves including edwards448 and its related group. Though the36* operations in this class are optimized for edwards448, they are correct37* for any untwisted Edwards curve x^2 + y^2 = 1 + dx^2y^2 (mod p) where38* d is not square (mod p).39*/40public class Ed448Operations extends EdECOperations {4142private final SmallValue two;43private final ImmutableIntegerModuloP d;44private final ProjectivePoint.Immutable basePoint;4546private static final BigInteger TWO = BigInteger.valueOf(2);47private static final BigInteger THREE = BigInteger.valueOf(3);48private static final BigInteger FIVE = BigInteger.valueOf(5);49private final BigInteger sizeMinus3;5051public Ed448Operations(ImmutableIntegerModuloP d, BigInteger baseX,52BigInteger baseY) {5354this.two = d.getField().getSmallValue(2);55this.d = d;56this.basePoint = of(new AffinePoint(57d.getField().getElement(baseX),58d.getField().getElement(baseY)59));6061this.sizeMinus3 = d.getField().getSize().subtract(THREE);62}6364@Override65public Point basePointMultiply(byte[] scalar) {66return setProduct(basePoint.mutable(), scalar);67}6869@Override70protected ProjectivePoint.Immutable getNeutral() {71IntegerFieldModuloP field = d.getField();72return new ProjectivePoint.Immutable(field.get0(), field.get1(),73field.get1());74}7576@Override77protected MutablePoint setSum(MutablePoint p1, MutablePoint p2,78MutableIntegerModuloP t1,79MutableIntegerModuloP t2,80MutableIntegerModuloP t3) {8182ProjectivePoint.Mutable ehp1 = (ProjectivePoint.Mutable) p1;83ProjectivePoint.Mutable ehp2 = (ProjectivePoint.Mutable) p2;84return setSum(ehp1, ehp2, t1, t2, t3);85}8687@Override88protected MutablePoint setDouble(MutablePoint p, MutableIntegerModuloP t1,89MutableIntegerModuloP t2) {9091ProjectivePoint.Mutable ehp = (ProjectivePoint.Mutable) p;92return setDouble(ehp, t1, t2);93}9495@Override96public ProjectivePoint.Immutable of(AffinePoint p) {97return new ProjectivePoint.Immutable(p.getX(), p.getY(),98p.getX().getField().get1());99}100101@Override102public <T extends Throwable>103AffinePoint decodeAffinePoint(Function<String, T> exception, int xLSB,104IntegerModuloP y) throws T {105106ImmutableIntegerModuloP y2 = y.square();107ImmutableIntegerModuloP u = y2.subtract(d.getField().get1());108MutableIntegerModuloP v = d.mutable().setProduct(y2)109.setDifference(d.getField().get1());110111IntegerModuloP u5v3pow = u.pow(FIVE).multiply(v.pow(THREE))112.pow(sizeMinus3.shiftRight(2));113114MutableIntegerModuloP x = v.mutable().setProduct(u.pow(THREE))115.setProduct(u5v3pow);116117v.setProduct(x).setProduct(x);118// v now holds vx^2119if (v.asBigInteger().equals(u.asBigInteger())) {120// x is correct121} else {122throw exception.apply("Invalid point");123}124125if (x.asBigInteger().equals(BigInteger.ZERO) && xLSB == 1) {126throw exception.apply("Invalid point");127}128129if (xLSB != x.asBigInteger().mod(TWO).intValue()) {130x.setAdditiveInverse();131}132133return new AffinePoint(x.fixed(), y.fixed());134}135136ProjectivePoint.Mutable setSum(137ProjectivePoint.Mutable p1,138ProjectivePoint.Mutable p2,139MutableIntegerModuloP t1,140MutableIntegerModuloP t2,141MutableIntegerModuloP t3) {142143t1.setValue(p1.getX()).setProduct(p2.getX());144// t1 holds C145t2.setValue(p2.getX()).setSum(p2.getY());146p1.getX().setSum(p1.getY()).setProduct(t2);147// x holds H148p1.getZ().setProduct(p2.getZ());149// z holds A150p1.getY().setProduct(p2.getY());151// y holds D152153t3.setValue(d).setProduct(t1).setProduct(p1.getY());154// t3 holds E155// do part of the final calculation of x and y to free up t1156p1.getX().setDifference(t1).setReduced().setDifference(p1.getY());157p1.getY().setDifference(t1);158t1.setValue(p1.getZ()).setSquare();159// t2 holds B160161t2.setValue(t1).setDifference(t3);162// t2 holds F163t1.setSum(t3);164// t1 holds G165166p1.getX().setProduct(t2).setProduct(p1.getZ());167p1.getY().setProduct(t1).setProduct(p1.getZ());168p1.getZ().setValue(t2.multiply(t1));169170return p1;171172}173174protected ProjectivePoint.Mutable setDouble(ProjectivePoint.Mutable p,175MutableIntegerModuloP t1,176MutableIntegerModuloP t2) {177178t2.setValue(p.getX()).setSquare();179// t2 holds C180p.getX().setSum(p.getY()).setSquare();181// x holds B182p.getY().setSquare();183// y holds D184p.getZ().setSquare();185// z holds H186187t1.setValue(t2).setSum(p.getY()).setReduced();188// t1 holds E189t2.setDifference(p.getY());190p.getY().setValue(t1).setProduct(t2);191192p.getZ().setProduct(two);193p.getZ().setAdditiveInverse().setSum(t1);194// z holds J195p.getX().setDifference(t1).setProduct(p.getZ());196p.getZ().setProduct(t1);197198return p;199}200}201202203