/** * @param seed the private key * @param spec the parameter specification for this key * @throws IllegalArgumentException if seed length is wrong or hash algorithm is unsupported */ public EdDSAPrivateKeySpec(byte[] seed, EdDSAParameterSpec spec) { int bd8 = spec.getCurve().getField().getb() / 8; if (seed.length != bd8) throw new IllegalArgumentException("seed length is wrong"); this.spec = spec; this.seed = seed; try { MessageDigest hash = MessageDigest.getInstance(spec.getHashAlgorithm()); // H(k) h = hash.digest(seed); /*a = BigInteger.valueOf(2).pow(b-2); for (int i=3;i<(b-2);i++) { a = a.add(BigInteger.valueOf(2).pow(i).multiply(BigInteger.valueOf(Utils.bit(h,i)))); }*/ // Saves ~0.4ms per key when running signing tests. // TODO: are these bitflips the same for any hash function? h[0] &= 248; h[bd8 - 1] &= 63; h[bd8 - 1] |= 64; a = Arrays.copyOfRange(h, 0, bd8); A = spec.getB().scalarMultiply(a); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException("Unsupported hash algorithm"); } }
/** * @since 0.9.25 */ @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof EdDSAParameterSpec)) return false; EdDSAParameterSpec s = (EdDSAParameterSpec) o; return hashAlgo.equals(s.getHashAlgorithm()) && curve.equals(s.getCurve()) && B.equals(s.getB()); } }
/** * Initialize directly from the hash. * getSeed() will return null if this constructor is used. * * @param spec the parameter specification for this key * @param h the private key * @throws IllegalArgumentException if hash length is wrong * @since 0.9.27 (GitHub issue #17) */ public EdDSAPrivateKeySpec(EdDSAParameterSpec spec, byte[] h) { int bd4 = spec.getCurve().getField().getb() / 4; if (h.length != bd4) throw new IllegalArgumentException("hash length is wrong"); int bd8 = bd4 / 2; this.seed = null; this.h = h; this.spec = spec; h[0] &= 248; h[bd8 - 1] &= 63; h[bd8 - 1] |= 64; a = Arrays.copyOfRange(h, 0, bd8); A = spec.getB().scalarMultiply(a); }
GroupElement R = key.getParams().getB().scalarMultiply(r); byte[] Rbyte = R.toByteArray();
GroupElement R = key.getParams().getB().doubleScalarMultiplyVariableTime( ((EdDSAPublicKey) key).getNegativeA(), h, Sbyte);
public static boolean compareEDDSAKeyParams(EdDSAParameterSpec s1, EdDSAParameterSpec s2) { if (Objects.equals(s1, s2)) { return true; } else if (s1 == null || s2 == null) { return false; // both null is covered by Objects#equals } else { return Objects.equals(s1.getHashAlgorithm(), s2.getHashAlgorithm()) && Objects.equals(s1.getCurve(), s2.getCurve()) && Objects.equals(s1.getB(), s2.getB()); } }
public static boolean compareEDDSAKeyParams(EdDSAParameterSpec s1, EdDSAParameterSpec s2) { if (Objects.equals(s1, s2)) { return true; } else if (s1 == null || s2 == null) { return false; // both null is covered by Objects#equals } else { return Objects.equals(s1.getHashAlgorithm(), s2.getHashAlgorithm()) && Objects.equals(s1.getCurve(), s2.getCurve()) && Objects.equals(s1.getB(), s2.getB()); } }
@Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof EdDSAParameterSpec)) return false; EdDSAParameterSpec s = (EdDSAParameterSpec) o; return hashAlgo.equals(s.getHashAlgorithm()) && curve.equals(s.getCurve()) && B.equals(s.getB()); } }
/** * @param seed the private key * @param spec the parameter specification for this key * @throws IllegalArgumentException if seed length is wrong or hash algorithm is unsupported */ public EdDSAPrivateKeySpec(byte[] seed, EdDSAParameterSpec spec) { if (seed.length != spec.getCurve().getField().getb()/8) throw new IllegalArgumentException("seed length is wrong"); this.spec = spec; this.seed = seed; try { MessageDigest hash = MessageDigest.getInstance(spec.getHashAlgorithm()); int b = spec.getCurve().getField().getb(); // H(k) h = hash.digest(seed); /*a = BigInteger.valueOf(2).pow(b-2); for (int i=3;i<(b-2);i++) { a = a.add(BigInteger.valueOf(2).pow(i).multiply(BigInteger.valueOf(Utils.bit(h,i)))); }*/ // Saves ~0.4ms per key when running signing tests. // TODO: are these bitflips the same for any hash function? h[0] &= 248; h[(b/8)-1] &= 63; h[(b/8)-1] |= 64; a = Arrays.copyOfRange(h, 0, b/8); A = spec.getB().scalarMultiply(a); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException("Unsupported hash algorithm"); } }
/** * Initialize directly from the hash. * getSeed() will return null if this constructor is used. * * @param spec the parameter specification for this key * @param h the private key * @throws IllegalArgumentException if hash length is wrong * @since 0.1.1 */ public EdDSAPrivateKeySpec(EdDSAParameterSpec spec, byte[] h) { if (h.length != spec.getCurve().getField().getb()/4) throw new IllegalArgumentException("hash length is wrong"); this.seed = null; this.h = h; this.spec = spec; int b = spec.getCurve().getField().getb(); h[0] &= 248; h[(b/8)-1] &= 63; h[(b/8)-1] |= 64; a = Arrays.copyOfRange(h, 0, b/8); A = spec.getB().scalarMultiply(a); }
GroupElement R = key.getParams().getB().scalarMultiply(r); byte[] Rbyte = R.toByteArray();
GroupElement R = key.getParams().getB().doubleScalarMultiplyVariableTime( ((EdDSAPublicKey) key).getNegativeA(), h, Sbyte);