Changeset b3c5974 for core


Ignore:
Timestamp:
Feb 19, 2019 1:12:26 PM (16 months ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
14ac8fe5
Parents:
af46e48
Message:

Crypto: Implement blinding (proposal 123)
Add sig type 11 for blinded keys

Location:
core/java/src/net/i2p/crypto
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • core/java/src/net/i2p/crypto/Blinding.java

    raf46e48 rb3c5974  
    2020
    2121    private static final SigType TYPE = SigType.EdDSA_SHA512_Ed25519;
     22    private static final SigType TYPER = SigType.RedDSA_SHA512_Ed25519;
    2223
    2324    private Blinding() {}
     
    2728     *
    2829     *  @param key must be SigType EdDSA_SHA512_Ed25519
    29      *  @param alpha the secret data
    30      *  @throws UnsupportedOperationException unless supported
     30     *  @param alpha must be SigType RedDSA_SHA512_Ed25519
     31     *  @return SigType RedDSA_SHA512_Ed25519
     32     *  @throws UnsupportedOperationException unless supported SigTypes
     33     *  @throws IllegalArgumentException on bad inputs
    3134     */
    3235    public static SigningPublicKey blind(SigningPublicKey key, SigningPrivateKey alpha) {
    33         if (key.getType() != TYPE && alpha.getType() != TYPE)
     36        if (key.getType() != TYPE || alpha.getType() != TYPER)
    3437            throw new UnsupportedOperationException();
    3538        try {
     
    3740            EdDSAPrivateKey ajk = SigUtil.toJavaEdDSAKey(alpha);
    3841            EdDSAPublicKey bjk = EdDSABlinding.blind(jk, ajk);
    39             return SigUtil.fromJavaKey(bjk, TYPE);
     42            return SigUtil.fromJavaKey(bjk, TYPER);
    4043        } catch (GeneralSecurityException gse) {
    4144            throw new IllegalArgumentException(gse);
     
    4750     *
    4851     *  @param key must be SigType EdDSA_SHA512_Ed25519
    49      *  @param alpha the secret data
    50      *  @throws UnsupportedOperationException unless supported
     52     *  @param alpha must be SigType RedDSA_SHA512_Ed25519
     53     *  @return SigType RedDSA_SHA512_Ed25519
     54     *  @throws UnsupportedOperationException unless supported SigTypes
     55     *  @throws IllegalArgumentException on bad inputs
    5156     */
    5257    public static SigningPrivateKey blind(SigningPrivateKey key, SigningPrivateKey alpha) {
    53         if (key.getType() != TYPE && alpha.getType() != TYPE)
     58        if (key.getType() != TYPE || alpha.getType() != TYPER)
    5459            throw new UnsupportedOperationException();
    5560        try {
     
    5762            EdDSAPrivateKey ajk = SigUtil.toJavaEdDSAKey(alpha);
    5863            EdDSAPrivateKey bjk = EdDSABlinding.blind(jk, ajk);
    59             return SigUtil.fromJavaKey(bjk, TYPE);
     64            return SigUtil.fromJavaKey(bjk, TYPER);
    6065        } catch (GeneralSecurityException gse) {
    6166            throw new IllegalArgumentException(gse);
     
    6671     *  Only for SigType EdDSA_SHA512_Ed25519.
    6772     *
    68      *  @param key must be SigType EdDSA_SHA512_Ed25519
    69      *  @param alpha the secret data
    70      *  @throws UnsupportedOperationException unless supported
     73     *  @param key must be SigType RedDSA_SHA512_Ed25519
     74     *  @param alpha must be SigType RedDSA_SHA512_Ed25519
     75     *  @return SigType EdDSA_SHA512_Ed25519
     76     *  @throws UnsupportedOperationException unless supported SigTypes
     77     *  @throws IllegalArgumentException on bad inputs
    7178     */
    7279    public static SigningPrivateKey unblind(SigningPrivateKey key, SigningPrivateKey alpha) {
    73         if (key.getType() != TYPE && alpha.getType() != TYPE)
     80        if (key.getType() != TYPER || alpha.getType() != TYPER)
    7481            throw new UnsupportedOperationException();
    7582        try {
     
    8289        }
    8390    }
     91
    8492/******
    8593    public static void main(String args[]) throws Exception {
    86         SimpleDataStructure[] keys = KeyGenerator.getInstance().generateSigningKeys(TYPE);
     94        net.i2p.data.SimpleDataStructure[] keys = KeyGenerator.getInstance().generateSigningKeys(TYPE);
    8795        SigningPublicKey pub = (SigningPublicKey) keys[0];
    8896        SigningPrivateKey priv = (SigningPrivateKey) keys[1];
    89         byte[] b = new byte[32];
     97        byte[] b = new byte[64];
    9098        net.i2p.I2PAppContext.getGlobalContext().random().nextBytes(b);
    91         Hash h = new Hash(b);
    92         SigningPublicKey bpub = blind(pub, h);
    93         SigningPrivateKey bpriv = blind(priv, h);
    94         SigningPublicKey bpub2 = bpriv.toPublic();
    95         boolean ok = bpub2.equals(bpub);
    96         System.out.println("Blinding test passed?   " + ok);
    97         SigningPrivateKey priv2 = unblind(bpriv, h);
    98         ok = priv2.equals(priv);
    99         System.out.println("Unblinding test passed? " + ok);
     99        b = EdDSABlinding.reduce(b);
     100        SigningPrivateKey alpha = new SigningPrivateKey(TYPER, b);
     101        SigningPublicKey bpub = null;
     102        try {
     103            bpub = blind(pub, alpha);
     104        } catch (Exception e) {
     105            System.out.println("Blinding pubkey test failed");
     106            e.printStackTrace();
     107        }
     108        SigningPrivateKey bpriv = null;
     109        try {
     110            bpriv = blind(priv, alpha);
     111        } catch (Exception e) {
     112            System.out.println("Blinding privkey test failed");
     113            e.printStackTrace();
     114        }
     115        if (bpub != null && bpriv != null) {
     116            SigningPublicKey bpub2 = bpriv.toPublic();
     117            boolean ok = bpub2.equals(bpub);
     118            System.out.println("Blinding test passed?   " + ok);
     119            // unimplemented
     120            //SigningPrivateKey priv2 = unblind(bpriv, alpha);
     121            //ok = priv2.equals(priv);
     122            //System.out.println("Unblinding test passed? " + ok);
     123        }
    100124    }
    101125******/
  • core/java/src/net/i2p/crypto/SigType.java

    raf46e48 rb3c5974  
    6565    EdDSA_SHA512_Ed25519ph(8, 32, 32, 64, 64, SigAlgo.EdDSA, "SHA-512", "NonewithEdDSA",
    6666                           EdDSANamedCurveTable.getByName("ed25519-sha-512"), "1.3.101.101", "0.9.25"),
     67
     68    // 9 and 10 reserved for GOST - see proposal 134
     69
     70    /**
     71     *  Blinded version of EdDSA, use for encrypted LS2
     72     *  Pubkey 32 bytes; privkey 32 bytes; hash 64 bytes; sig 64 bytes
     73     *
     74     *  @since 0.9.39
     75     */
     76    RedDSA_SHA512_Ed25519(11, 32, 32, 64, 64, SigAlgo.EdDSA, "SHA-512", "SHA512withEdDSA",
     77                          EdDSANamedCurveTable.getByName("ed25519-sha-512"), "1.3.101.101", "0.9.39"),
    6778
    6879    ;
     
    296307            if (uc.equals("EDDSA_SHA512_ED25519PH"))
    297308                return EdDSA_SHA512_Ed25519ph;
     309            if (uc.equals("REDDSA_SHA512_ED25519"))
     310                return RedDSA_SHA512_Ed25519;
    298311            return valueOf(uc);
    299312        } catch (IllegalArgumentException iae) {
  • core/java/src/net/i2p/crypto/SigUtil.java

    raf46e48 rb3c5974  
    370370                              throws GeneralSecurityException {
    371371        try {
    372             return new EdDSAPrivateKey(new EdDSAPrivateKeySpec(
    373                 pk.getData(), (EdDSAParameterSpec) pk.getType().getParams()));
     372            EdDSAParameterSpec paramspec = (EdDSAParameterSpec) pk.getType().getParams();
     373            EdDSAPrivateKeySpec pkspec;
     374            SigType type = pk.getType();
     375            if (type == SigType.EdDSA_SHA512_Ed25519)
     376                pkspec = new EdDSAPrivateKeySpec(pk.getData(), paramspec);
     377            else if (type == SigType.RedDSA_SHA512_Ed25519)
     378                pkspec = new EdDSAPrivateKeySpec(pk.getData(), null, paramspec);
     379            else
     380                throw new InvalidKeyException();
     381            return new EdDSAPrivateKey(pkspec);
    374382        } catch (IllegalArgumentException iae) {
    375383            throw new InvalidKeyException(iae);
     
    390398    public static SigningPrivateKey fromJavaKey(EdDSAPrivateKey pk, SigType type)
    391399            throws GeneralSecurityException {
    392         return new SigningPrivateKey(type, pk.getSeed());
     400        byte[] data;
     401        if (type == SigType.EdDSA_SHA512_Ed25519)
     402            data = pk.getSeed();
     403        else if (type == SigType.RedDSA_SHA512_Ed25519)
     404            data = pk.geta();
     405        else
     406            throw new IllegalArgumentException();
     407        return new SigningPrivateKey(type, data);
    393408    }
    394409
  • core/java/src/net/i2p/crypto/eddsa/EdDSABlinding.java

    raf46e48 rb3c5974  
    11package net.i2p.crypto.eddsa;
     2
     3import java.math.BigInteger;
     4
     5import net.i2p.crypto.eddsa.math.Field;
     6import net.i2p.crypto.eddsa.math.GroupElement;
     7import net.i2p.crypto.eddsa.math.ScalarOps;
     8import net.i2p.crypto.eddsa.math.bigint.BigIntegerLittleEndianEncoding;
     9import net.i2p.crypto.eddsa.math.bigint.BigIntegerScalarOps;
     10import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
     11import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
     12import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
    213
    314/**
     
    819 */
    920public final class EdDSABlinding {
     21
     22    private static final byte[] ONE = Utils.hexToBytes("0100000000000000000000000000000000000000000000000000000000000000");
     23    private static final Field FIELD = EdDSANamedCurveTable.getByName("Ed25519").getCurve().getField();
     24    private static final BigInteger ORDER = new BigInteger("2").pow(252).add(new BigInteger("27742317777372353535851937790883648493"));
    1025
    1126    private EdDSABlinding() {}
     
    1934     */
    2035    public static EdDSAPublicKey blind(EdDSAPublicKey key, EdDSAPrivateKey alpha) {
    21         // TODO, test only
    22         return key;
     36        GroupElement a = key.getA();
     37        GroupElement aa = alpha.getA();
     38        // Add the two public keys together.
     39        GroupElement d = a.add(aa.toCached());
     40        EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(d, key.getParams());
     41        EdDSAPublicKey rv = new EdDSAPublicKey(pubKey);
     42        //System.out.println("Adding pubkey\n" +
     43        //   net.i2p.util.HexDump.dump(key.getAbyte()) +
     44        //   "\nplus privkey\n" +
     45        //   net.i2p.util.HexDump.dump(alpha.geta()) +
     46        //   "\nequals\n" +
     47        //   net.i2p.util.HexDump.dump(rv.getAbyte()));
     48        return rv;
    2349    }
    2450
     
    3157     */
    3258    public static EdDSAPrivateKey blind(EdDSAPrivateKey key, EdDSAPrivateKey alpha) {
    33         // TODO, test only
    34         return key;
     59        byte[] a = key.geta();
     60        byte[] aa = alpha.geta();
     61        Field f = key.getParams().getCurve().getField();
     62        BigIntegerLittleEndianEncoding enc = new BigIntegerLittleEndianEncoding();
     63        enc.setField(f);
     64        ScalarOps sc = new BigIntegerScalarOps(f, ORDER);
     65        // Add the two private keys together.
     66        // just for now, since we don't have a pure add.
     67        byte[] d = sc.multiplyAndAdd(ONE, a, aa);
     68        //System.out.println("Adding privkeys\n" +
     69        //   net.i2p.util.HexDump.dump(a) +
     70        //   "\nplus\n" +
     71        //   net.i2p.util.HexDump.dump(aa) +
     72        //   "\nequals\n" +
     73        //   net.i2p.util.HexDump.dump(d));
     74        EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(d, null, key.getParams());
     75        return new EdDSAPrivateKey(privKey);
    3576    }
    3677
    3778    /**
    38      *  Only for SigType EdDSA_SHA512_Ed25519.
     79     *  Unimplemented, probably not needed except for testing.
    3980     *
    4081     *  @param key must be SigType EdDSA_SHA512_Ed25519
     
    4384     */
    4485    public static EdDSAPrivateKey unblind(EdDSAPrivateKey key, EdDSAPrivateKey alpha) {
    45         // TODO, test only
    46         return key;
     86        throw new UnsupportedOperationException();
     87    }
     88
     89    /**
     90     *  Use to generate alpha
     91     *
     92     *  @param b 64 bytes little endian of random
     93     *  @return 32 bytes little endian mod l
     94     */
     95    public static byte[] reduce(byte[] b) {
     96        if (b.length != 64)
     97            throw new IllegalArgumentException();
     98        ScalarOps sc = new BigIntegerScalarOps(FIELD, ORDER);
     99        return sc.reduce(b);
    47100    }
    48101}
  • core/java/src/net/i2p/crypto/eddsa/spec/EdDSAPrivateKeySpec.java

    raf46e48 rb3c5974  
    8484    }
    8585
     86    /**
     87     *  No validation of any parameters other than a.
     88     *  getSeed() and getH() will return null if this constructor is used.
     89     *
     90     *  @param a must be "clamped" (for Ed) or reduced mod l (for Red)
     91     *  @param A if null, will be derived from a.
     92     *  @throws IllegalArgumentException if a not clamped or reduced
     93     *  @since 0.9.39
     94     */
     95    public EdDSAPrivateKeySpec(byte[] a, GroupElement A, EdDSAParameterSpec spec) {
     96        this(null, null, a, A, spec);
     97    }
     98
     99    /**
     100     *  No validation of any parameters other than a.
     101     *
     102     *  @param seed may be null
     103     *  @param h may be null
     104     *  @param a must be "clamped" (for Ed) or reduced mod l (for Red)
     105     *  @param A if null, will be derived from a.
     106     *  @throws IllegalArgumentException if a not clamped or reduced
     107     */
    86108    public EdDSAPrivateKeySpec(byte[] seed, byte[] h, byte[] a, GroupElement A, EdDSAParameterSpec spec) {
     109/**
     110        // TODO if we move RedDSA to a different spec
     111        int bd8m1 = (spec.getCurve().getField().getb() / 8) - 1;
     112        if ((a[0] & 0x07) != 0 ||
     113            (a[bd8m1] & 0xc0) != 0x40)
     114            throw new IllegalArgumentException("a not clamped: a[0]=0x" + Integer.toString(a[0] & 0xff, 16) +
     115                                                             " a[31]=0x" + Integer.toString(a[31] & 0xff, 16));
     116**/
    87117        this.seed = seed;
    88118        this.h = h;
    89119        this.a = a;
    90         this.A = A;
     120        this.A = (A != null) ? A : spec.getB().scalarMultiply(a);
    91121        this.spec = spec;
    92122    }
Note: See TracChangeset for help on using the changeset viewer.