1 package org.bouncycastle.math.ec.endo; 2 3 import java.math.BigInteger; 4 5 import org.bouncycastle.math.ec.ECConstants; 6 import org.bouncycastle.math.ec.ECCurve; 7 import org.bouncycastle.math.ec.ECPointMap; 8 import org.bouncycastle.math.ec.ScaleXPointMap; 9 10 public class GLVTypeBEndomorphism implements GLVEndomorphism 11 { 12 protected final ECCurve curve; 13 protected final GLVTypeBParameters parameters; 14 protected final ECPointMap pointMap; 15 16 public GLVTypeBEndomorphism(ECCurve curve, GLVTypeBParameters parameters) 17 { 18 this.curve = curve; 19 this.parameters = parameters; 20 this.pointMap = new ScaleXPointMap(curve.fromBigInteger(parameters.getBeta())); 21 } 22 23 public BigInteger[] decomposeScalar(BigInteger k) 24 { 25 int bits = parameters.getBits(); 26 BigInteger b1 = calculateB(k, parameters.getG1(), bits); 27 BigInteger b2 = calculateB(k, parameters.getG2(), bits); 28 29 GLVTypeBParameters p = parameters; 30 BigInteger a = k.subtract((b1.multiply(p.getV1A())).add(b2.multiply(p.getV2A()))); 31 BigInteger b = (b1.multiply(p.getV1B())).add(b2.multiply(p.getV2B())).negate(); 32 33 return new BigInteger[]{ a, b }; 34 } 35 36 public ECPointMap getPointMap() 37 { 38 return pointMap; 39 } 40 41 public boolean hasEfficientPointMap() 42 { 43 return true; 44 } 45 46 protected BigInteger calculateB(BigInteger k, BigInteger g, int t) 47 { 48 boolean negative = (g.signum() < 0); 49 BigInteger b = k.multiply(g.abs()); 50 boolean extra = b.testBit(t - 1); 51 b = b.shiftRight(t); 52 if (extra) 53 { 54 b = b.add(ECConstants.ONE); 55 } 56 return negative ? b.negate() : b; 57 } 58 } 59