All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.siisise.security.sign.DSAKeyGen Maven / Gradle / Ivy

/*
 * Copyright 2023 okome.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.siisise.security.sign;

import java.math.BigInteger;
import net.siisise.ietf.pkcs1.PKCS1;
import net.siisise.io.Packet;
import net.siisise.io.PacketA;
import net.siisise.lang.Bin;
import net.siisise.security.digest.SHA1;

/**
 * DSAのDomainとx y 鍵生成.
 * FIPS PUB 186-4 DSS Section 4
 * 
 */
public class DSAKeyGen {
    
    static class LNPair {
        final int L;
        final int N;
        
        LNPair(int l, int n) {
            L = l;
            N = n;
        }
        
        boolean equals( int l, int n) {
            return (L == l) && (N == n);
        }
        
        @Override
        public boolean equals(Object o) {
            if ( o instanceof LNPair ) {
                return ((LNPair)o).L == L && ((LNPair)o).N == N;
            }
            return false;
        }
    }

    /**
     * FIPS PUB 186-4 で指定可能なのは4種類のみ.
     */
    public static final LNPair LN1016 = new LNPair(1024, 160);
    public static final LNPair LN2022 = new LNPair(2048, 224);
    public static final LNPair LN2025 = new LNPair(2048, 256);
    public static final LNPair LN3025 = new LNPair(3072, 256);
    
    
    /**
     * ひととおりDSAで使える秘密鍵を生成する。
     * @return 新規の秘密鍵
     */
    DSAPrivateKey gen(LNPair lp) {
        DSADomain domain = genDomain(lp);
        return genPrivateKey(domain);
    }

    /**
     * DSAのDomain に x を加えて秘密鍵を生成する。
     * SSH などは固定 domainがあるらしい。
     * @param domain
     * @return 
     */
    DSAPrivateKey genPrivateKey(DSADomain domain) {
        throw new java.lang.UnsupportedOperationException("まだない");
    }
    
    /**
     * 
     * @return ランダムなようなそうでないような.
     */
    BigInteger genK() {
        throw new java.lang.UnsupportedOperationException("まだない");
    }
    
    /**
     * DSA の Domain 要素を生成するよ。
     * 
     * FIPS 186-4
     * 4.3.1
     * 付録 A.1 p, q の生成
     * 
     * p, q, g
     * 
     * @return DSADomain
     */
    DSADomain genDomain(LNPair ln) {
        
        BigInteger p;
        BigInteger q;
        
        BigInteger g;
        
        throw new java.lang.UnsupportedOperationException("まだない");
    }
    
    private DSADomain a1(LNPair ln) {
        throw new java.lang.UnsupportedOperationException();
    }
    
    private DSADomain a11(LNPair ln) {
        throw new java.lang.UnsupportedOperationException();
    }
    
    /**
     * SHA-1 を使った古い方法 の検証.
     * L 1024 N 160 相当.
     * @param ln
     * @return true VALID / false INVALID
     * @deprecated 古いものの検証用
     */
    @Deprecated
    private boolean a111(BigInteger p, BigInteger q, BigInteger domainParameterSeed, int counter) {
        if ( p.bitLength() != 1024 || q.bitLength() != 160 ) return false; // 1
        if ( counter > 4095 ) return false; // 2
        int seedlen = domainParameterSeed.bitLength(); // 3
        if ( seedlen < 160 ) return false; // 4
        // 5
        byte[] seed = toBin(domainParameterSeed);
        SHA1 sha = new SHA1();
        byte[] shaSeed = sha.digest(seed);
        Bin.inc(seed);
        byte[] plusSeed = sha.digest(seed);
        Bin.xorl(shaSeed, plusSeed);
        shaSeed[0] |= 0x80; // 6
        shaSeed[shaSeed.length - 1] |= 1;
        if ( !testC3(toNum(shaSeed))) return false; // 7
        int offset = 2; // 8
        //byte[][] v = new byte[6][];
        int i;
        BigInteger computed_p = null;
        for ( i = 0; i <= counter; i++ ) {
            Packet v = new PacketA();
            for ( int j = 0; j <= 6; j++ ) {
                v.backWrite( sha.digest(toBin(domainParameterSeed.add(BigInteger.valueOf(offset + j)))));
            }
            byte[] W = new byte[128]; // 1024 / 8
            v.backRead(W);
            W[0] |= 0x80;
            BigInteger X = toNum(W);
            BigInteger c = X.mod(q.shiftLeft(1));
            computed_p = X.subtract(c).add(BigInteger.ONE);
            if ( computed_p.compareTo(BigInteger.ONE.shiftLeft(1023)) >= 0 ) {
                if ( testC3(computed_p) ) { // 9.7
                    break;
                }
            }
            offset += 7;
        
        }
        // 10
        return ( i == counter &&  p.equals(computed_p) && testC3(computed_p));
    }

    /**
     * バイト列変換.
     * ToDo: 仮
     * @param num 数値
     * @return バイト列
     */
    byte[] toBin(BigInteger num) {
        return PKCS1.I2OSP(num, (num.bitLength() + 7) / 8);
    }
    
    BigInteger toNum(byte[] bin) {
        return PKCS1.OS2IP(bin);
    }
    
    /**
     * A.1.1.2 確率的手法
     * @param ln
     * @return 
     */
    private DSADomain a112(LNPair ln, int seedlen) {
        throw new java.lang.UnsupportedOperationException();
    }
    
    /**
     * A.1.1.3
     * A.1.1.2 の検証
     * @param d
     * @return 
     */
    private boolean a113valid(DSADomain d) {
        throw new java.lang.UnsupportedOperationException();
        
    }
    
    boolean testC3(BigInteger n) {
        throw new java.lang.UnsupportedOperationException();
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy