Path: blob/master/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/Ed25519Operations.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/*33* Elliptic curve point arithmetic, decoding, and other operations for the34* family of curves including edwards25519 and its related group. Though the35* operations in this class are optimized for edwards25519, they are correct36* for any twisted Edwards curve ax^2 + y^2 = 1 + dx^2y^2 (mod p) with the37* following properties:38* 1) a = -1 (mod p)39* 2) a is square (mod p)40* 3) d is not square (mod p)41*/42public class Ed25519Operations extends EdECOperations {4344private final SmallValue two;45private final ImmutableIntegerModuloP d;46private final ExtendedHomogeneousPoint.Immutable basePoint;4748private static final BigInteger TWO = BigInteger.valueOf(2);49private static final BigInteger SEVEN = BigInteger.valueOf(7);50private final BigInteger sizeMinus5;5152public Ed25519Operations(ImmutableIntegerModuloP d, BigInteger baseX,53BigInteger baseY) {5455this.two = d.getField().getSmallValue(2);56this.d = d;57this.basePoint = of(new AffinePoint(58d.getField().getElement(baseX), d.getField().getElement(baseY)59));60this.sizeMinus5 =61d.getField().getSize().subtract(BigInteger.valueOf(5));62}6364@Override65public Point basePointMultiply(byte[] scalar) {66return setProduct(basePoint.mutable(), scalar);67}6869@Override70protected ExtendedHomogeneousPoint.Immutable getNeutral() {71IntegerFieldModuloP field = d.getField();72return new ExtendedHomogeneousPoint.Immutable(field.get0(),73field.get1(), field.get0(), field.get1());74}7576@Override77protected MutablePoint setSum(MutablePoint p1, MutablePoint p2,78MutableIntegerModuloP t1,79MutableIntegerModuloP t2,80MutableIntegerModuloP t3) {8182ExtendedHomogeneousPoint.Mutable ehp1 =83(ExtendedHomogeneousPoint.Mutable) p1;84ExtendedHomogeneousPoint.Mutable ehp2 =85(ExtendedHomogeneousPoint.Mutable) p2;86return setSum(ehp1, ehp2, t1, t2, t3);87}8889@Override90protected MutablePoint setDouble(MutablePoint p, MutableIntegerModuloP t1,91MutableIntegerModuloP t2) {9293ExtendedHomogeneousPoint.Mutable ehp =94(ExtendedHomogeneousPoint.Mutable) p;95return setDouble(ehp, t1, t2);96}9798@Override99public ExtendedHomogeneousPoint.Immutable of(AffinePoint p) {100return new ExtendedHomogeneousPoint.Immutable(p.getX(), p.getY(),101p.getX().multiply(p.getY()), p.getX().getField().get1());102}103104@Override105public <T extends Throwable>106AffinePoint decodeAffinePoint(Function<String, T> exception,107int xLSB, IntegerModuloP y) throws T {108109IntegerFieldModuloP field = d.getField();110BigInteger p = field.getSize();111ImmutableIntegerModuloP y2 = y.square();112ImmutableIntegerModuloP u = y2.subtract(field.get1());113MutableIntegerModuloP v = d.mutable().setProduct(y2)114.setSum(field.get1());115116MutableIntegerModuloP x =117u.mutable().setProduct(v.pow(BigInteger.valueOf(3)));118ImmutableIntegerModuloP uv7pow =119u.multiply(v.pow(SEVEN)).pow(sizeMinus5.shiftRight(3));120x.setProduct(uv7pow);121122v.setProduct(x).setProduct(x);123// v now holds vx^2124BigInteger bigVX2 = v.asBigInteger();125if (bigVX2.equals(u.asBigInteger())) {126// do nothing---x is correct127} else if (bigVX2.equals(u.additiveInverse().asBigInteger())) {128BigInteger exp = p.subtract(BigInteger.ONE).shiftRight(2);129IntegerModuloP twoPow = field.getElement(TWO.modPow(exp, p));130x.setProduct(twoPow);131} else {132throw exception.apply("Invalid point");133}134135if (x.asBigInteger().equals(BigInteger.ZERO) && xLSB == 1) {136throw exception.apply("Invalid point");137}138139if (xLSB != x.asBigInteger().mod(BigInteger.valueOf(2)).intValue()) {140x.setAdditiveInverse();141}142143return new AffinePoint(x.fixed(), y.fixed());144}145146ExtendedHomogeneousPoint.Mutable setSum(147ExtendedHomogeneousPoint.Mutable p1,148ExtendedHomogeneousPoint.Mutable p2,149MutableIntegerModuloP t1,150MutableIntegerModuloP t2,151MutableIntegerModuloP t3) {152153t1.setValue(p2.getY()).setDifference(p2.getX());154// t1 holds y2 - x2155t2.setValue(p1.getY()).setDifference(p1.getX()).setProduct(t1);156// t2 holds A = (y1 - x1) * (y2 - x2)157t1.setValue(p2.getY()).setSum(p2.getX());158// t1 holds y2 + x2159t3.setValue(p1.getY()).setSum(p1.getX()).setProduct(t1);160// t3 holds B = (y1 + x1) * (y2 + x2)161p1.getX().setValue(t3).setDifference(t2);162// x holds E = B - A163t3.setSum(t2);164// t3 holds H = B + A, t2 is unused165t2.setValue(d).setSum(d).setProduct(p1.getT()).setProduct(p2.getT());166// t2 holds C167t1.setValue(p1.getZ()).setProduct(p2.getZ()).setProduct(two);168// t1 holds D169p1.getY().setValue(t1).setSum(t2);170// y holds G171p1.getZ().setValue(t1).setDifference(t2);172// z holds F173174p1.getT().setValue(p1.getX()).setProduct(t3);175p1.getX().setProduct(p1.getZ());176p1.getZ().setProduct(p1.getY());177p1.getY().setProduct(t3);178179return p1;180181}182183protected ExtendedHomogeneousPoint.Mutable setDouble(184ExtendedHomogeneousPoint.Mutable p,185MutableIntegerModuloP t1, MutableIntegerModuloP t2) {186187t1.setValue(p.getX()).setSum(p.getY()).setSquare();188// t1 holds (x + y)^2189p.getX().setSquare();190// x = A = x^2191p.getY().setSquare();192// y = B = y^2193t2.setValue(p.getX()).setSum(p.getY()).setReduced();194// t2 holds H195p.getZ().setSquare().setProduct(two);196// z holds C197198p.getT().setValue(t2).setDifference(t1);199// t holds E200t1.setValue(p.getX()).setDifference(p.getY()).setReduced();201// t1 holds G202203p.getZ().setSum(t1);204// z holds F205206p.getX().setValue(p.getT()).setProduct(p.getZ());207p.getY().setValue(t1).setProduct(t2);208p.getT().setProduct(t2);209p.getZ().setProduct(t1);210211return p;212}213}214215216