On Sun, Sep 24, 2006 at 01:03:18AM +0000, nextgens at freenetproject.org wrote:
> Author: nextgens
> Date: 2006-09-24 01:02:49 +0000 (Sun, 24 Sep 2006)
> New Revision: 10505
> 
> Modified:
>    trunk/freenet/src/freenet/crypt/DSA.java
>    trunk/freenet/src/freenet/crypt/DSAGroup.java
> Log:
> Fix some crypto code: 
>       1) we were generating the "h" parameter of the group with only a few 
> bytes

Eh? h is the number of bits of another parameter; it's supposed to be short!
Hmmm, having said that, our Q length needs to be the same as our hash
length, i.e. 256. Which code did we actually use for group generation?
I'm reasonably sure I generated a group with 2048/256...

Having to change group would be rather destructive, please could you
give a detailed justification?

>       2) we weren't verifying DSA signatures as we ought to
> 
> TODO: what about following FIPS-186-3 insteed of the first version ?

I don't think it was available at the time of implementation.
> 
> Of course it needs to be carefully reviewed... and hasn't been tested ;p
> 
> Modified: trunk/freenet/src/freenet/crypt/DSA.java
> ===================================================================
> --- trunk/freenet/src/freenet/crypt/DSA.java  2006-09-23 22:47:03 UTC (rev 
> 10504)
> +++ trunk/freenet/src/freenet/crypt/DSA.java  2006-09-24 01:02:49 UTC (rev 
> 10505)
> @@ -14,23 +14,20 @@
>       * Returns a DSA signature given a group, private key (x), a random nonce
>       * (k), and the hash of the message (m).
>       */
> -    public static DSASignature sign(DSAGroup g,
> -                                 DSAPrivateKey x,
> -                                 BigInteger k, 
> -                                 BigInteger m) {
> +     public static DSASignature sign(DSAGroup g,
> +                     DSAPrivateKey x,
> +                     BigInteger k, 
> +                     BigInteger m) {
>               BigInteger r=g.getG().modPow(k, g.getP()).mod(g.getQ());
> -             
> +
>               BigInteger kInv=k.modInverse(g.getQ());
>               return sign(g, x, r, kInv, m);
> -    } 
> -     
> -    public static DSASignature sign(DSAGroup g, DSAPrivateKey x, BigInteger 
> m,
> -                                 Random r) {
> -     BigInteger k;
> -     do {
> -         k=new NativeBigInteger(256, r);
> -     } while ((k.compareTo(g.getQ())>-1) || 
> (k.compareTo(BigInteger.ZERO)==0));
> -     return sign(g, x, k, m);
> +     } 
> +
> +     public static DSASignature sign(DSAGroup g, DSAPrivateKey x, BigInteger 
> m,
> +                     Random r) {
> +             BigInteger k = DSA.generateK(g, r);
> +             return sign(g, x, k, m);
>      }
>  
>      /**
> @@ -41,10 +38,7 @@
>               BigInteger[][] result=new BigInteger[count][2];
>               
>               for (int i=0; i<count; i++) {
> -                     BigInteger k;
> -                     do {
> -                             k=new NativeBigInteger(160, r);
> -                     } while ((k.compareTo(g.getQ())>-1) || 
> (k.compareTo(BigInteger.ZERO)==0));
> +                     BigInteger k = DSA.generateK(g, r);
>                       
>                       result[i][0] = g.getG().modPow(k, g.getP()); // r 
>                       result[i][1] = k.modInverse(g.getQ()); // k^-1 
> @@ -60,10 +54,20 @@
>      public static DSASignature sign(DSAGroup g, DSAPrivateKey x,
>                                   BigInteger r, BigInteger kInv, 
>                                   BigInteger m) {
> -     BigInteger s1=m.add(x.getX().multiply(r)).mod(g.getQ());
> -     BigInteger s=kInv.multiply(s1).mod(g.getQ());
> -     return new DSASignature(r,s);
> +     BigInteger s1=m.add(x.getX().multiply(r)).mod(g.getQ());
> +     BigInteger s=kInv.multiply(s1).mod(g.getQ());
> +     // FIXME: the following case would involve recomputing the sig. with a 
> different k 
> +     if((r.compareTo(BigInteger.ZERO) == 0) || (s.compareTo(BigInteger.ZERO) 
> == 0)) throw new NullPointerException("Something is wrong there!");
> +     return new DSASignature(r,s);
>      }
> +    
> +    private static BigInteger generateK(DSAGroup g, Random r){
> +             BigInteger k;
> +             do {
> +                     k=new NativeBigInteger(DSAGroup.Q_BIT_LENGTH, r);
> +             } while ((g.getQ().compareTo(k) < 1) || 
> (k.compareTo(BigInteger.ZERO) == 0));
> +             return k;
> +    }
>  
>      /**
>       * Verifies the message authenticity given a group, the public key
> @@ -73,7 +77,12 @@
>                                DSASignature sig,
>                                BigInteger m) {
>       try {
> -         BigInteger w=sig.getS().modInverse(kp.getQ());
> +             // 0<r<q has to be true
> +             if((sig.getR().compareTo(BigInteger.ZERO) < 1) || 
> (kp.getQ().compareTo(sig.getR()) < 1)) return false;
> +             // 0<s<q has to be true as well
> +             if((sig.getS().compareTo(BigInteger.ZERO) < 1) || 
> (kp.getQ().compareTo(sig.getS()) < 1)) return false;
> +             
> +             BigInteger w=sig.getS().modInverse(kp.getQ());
>           BigInteger u1=m.multiply(w).mod(kp.getQ());
>           BigInteger u2=sig.getR().multiply(w).mod(kp.getQ());
>           BigInteger v1=kp.getG().modPow(u1, kp.getP());
> @@ -81,7 +90,6 @@
>           BigInteger v=v1.multiply(v2).mod(kp.getP()).mod(kp.getQ());
>           return v.equals(sig.getR());
>  
> -
>           //FIXME: is there a better way to handle this exception raised on 
> the 'w=' line above?
>       } catch (ArithmeticException e) {  // catch error raised by invalid data
>           return false;                  // and report that that data is bad.
> 
> Modified: trunk/freenet/src/freenet/crypt/DSAGroup.java
> ===================================================================
> --- trunk/freenet/src/freenet/crypt/DSAGroup.java     2006-09-23 22:47:03 UTC 
> (rev 10504)
> +++ trunk/freenet/src/freenet/crypt/DSAGroup.java     2006-09-24 01:02:49 UTC 
> (rev 10505)
> @@ -21,6 +21,8 @@
>   */
>  public class DSAGroup extends CryptoKey {
>       private static final long serialVersionUID = -1;
> +     
> +     public static final int Q_BIT_LENGTH = 160;
>  
>      private BigInteger p, q, g;
>  
> @@ -171,7 +173,7 @@
>  
>          public void run() {
>              while (true) {
> -                qs.addElement(makePrime(160, 80, r));
> +                qs.addElement(makePrime(DSAGroup.Q_BIT_LENGTH, 80, r));
>                  synchronized (this) {
>                      notifyAll();
>                  }
> @@ -239,7 +241,7 @@
>                      qg.notify();
>                  }
>              } else
> -                q = makePrime(160, 80, r);
> +                q = makePrime(DSAGroup.Q_BIT_LENGTH, 80, r);
>  
>              BigInteger X = new BigInteger(bits, r).setBit(bits - 1);
>  
> @@ -252,7 +254,7 @@
>          BigInteger h;
>          do {
>              if ((cc++) % 5 == 0) System.err.print("+");
> -            h = new NativeBigInteger(160, r);
> +            h = new NativeBigInteger(bits, r);
>              g = h.modPow(pmin1.divide(q), p);
>          } while ((h.compareTo(p.subtract(BigInteger.ONE)) != -1)
>                  || (h.compareTo(BigInteger.ONE) < 1)
> @@ -267,8 +269,9 @@
>          q = grp.getQ();
>          g = grp.getG();
>          BigInteger pmin1 = p.subtract(BigInteger.ONE);
> +        // TODO: that's FIPS-186-1, we should consider implementing 3 
> insteed!
>          boolean rv = !((p.bitLength() > 1024) || (p.bitLength() < 512))
> -                && ((p.bitLength() % 64) == 0) && (q.bitLength() == 160)
> +                && ((p.bitLength() % 64) == 0) && (q.bitLength() == 
> DSAGroup.Q_BIT_LENGTH)
>                  && (q.compareTo(p) == -1) && isPrime(p, 80) && isPrime(q, 80)
>                  && pmin1.mod(q).equals(BigInteger.ZERO)
>                  && (g.compareTo(BigInteger.ONE) == 1)
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: 
<https://emu.freenetproject.org/pipermail/devl/attachments/20060925/28157a77/attachment.pgp>

Reply via email to