Реализация назначенной подписи верификатора иногда приводит к неудаче - PullRequest
0 голосов
/ 26 февраля 2020

enter image description here enter image description here

Я пытаюсь внедрить схему верификатора, назначенную JSO Java. Я следую за бумагой выше, чтобы осуществить это. Но я получаю очень странный результат, который иногда является успешным, а иногда неудачным.

Вот пример успеха и неудачи. стрелка шириной в две является результатом проверки LHS и RHS на бумаге.

Неудачный случай

JSI Designated Verifier Signature Instance : JSIDVS : [
   p=11,
   q=5,
   g=5,
]
keyPairA = KeyPair : [
   privateKey=2,
   publicKey=3,
]
keyPairB = KeyPair : [
   privateKey=2,
   publicKey=3,
]
w = 3
r = 2
t = 3
Signature sign by A : JSIDVSSignature : [
   s=4,
   w=3,
   r=2,
   G=4,
   M=8,
   d=4,
]
9 <--> 9
6 <--> 5
false

Успешный случай

JSI Designated Verifier Signature Instance : JSIDVS : [
   p=11,
   q=5,
   g=4,
]
keyPairA = KeyPair : [
   privateKey=4,
   publicKey=3,
]
keyPairB = KeyPair : [
   privateKey=4,
   publicKey=3,
]
w = 3
r = 4
t = 2
Signature sign by A : JSIDVSSignature : [
   s=5,
   w=3,
   r=4,
   G=5,
   M=4,
   d=2,
]
5 <--> 5
4 <--> 4
true

А ниже мой код в Java.

package hk.jeff.dvs;

import hk.jeff.CryptoUtils;
import hk.jeff.model.KeyPair;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.security.Signature;

public class JSIDVS {
    protected static int RADIX = 10;

    private int size;

    BigInteger p;
    BigInteger q;
    BigInteger g;

    public JSIDVS(BigInteger p, BigInteger q, BigInteger g){
        this.p = p;
        this.q = q;
        this.g = g;
    }

    public JSIDVS(int size){
        this.size = size;
        SecureRandom random = new SecureRandom();
        BigInteger[] primes = CryptoUtils.generateSafePrimes(this.size, 100, random);
        this.p = primes[0];
        this.q = primes[1];
        this.g = CryptoUtils.selectGenerator(p, q, random);
    }

    @Override
    public String toString() {
        return "JSIDVS : [\n" +
                "   p=" + p.toString(RADIX) + ",\n" +
                "   q=" + q.toString(RADIX) + ",\n" +
                "   g=" + g.toString(RADIX) + ",\n" +
                "]";
    }

    public KeyPair generateKeyPair(){
        BigInteger x = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
        BigInteger y = this.g.modPow(x, this.p);

        KeyPair kp = new KeyPair();
        kp.setPublicKey(y);
        kp.setPrivateKey(x);

        return kp;
    }

    public JSIDVSSignature sign(BigInteger priKeyA, BigInteger pubKeyB, BigInteger m){
        JSIDVSSignature signature = new JSIDVSSignature();

        BigInteger w = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
        BigInteger r = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
        BigInteger t = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
//        BigInteger w = BigInteger.valueOf(57);
//        BigInteger r = BigInteger.valueOf(403);
//        BigInteger t = BigInteger.valueOf(383);

        System.out.println("w = " + w);
        System.out.println("r = " + r);
        System.out.println("t = " + t);

        BigInteger s = m.modPow(priKeyA, p);

        BigInteger c = (CryptoUtils.pow(g, w).multiply(CryptoUtils.pow(pubKeyB, r))).mod(p);
        BigInteger G = g.modPow(t, p);
        BigInteger M = m.modPow(t, p);

        BigInteger h = this.hashq(c, G, M);
        BigInteger d = t.add((priKeyA.multiply(h.add(w))).mod(q));

        signature.s = s;
        signature.w = w;
        signature.r = r;
        signature.G = G;
        signature.M = M;
        signature.d = d;

        return signature;
    }

    public Boolean verify(JSIDVSSignature signature, BigInteger m, BigInteger pubKeyA, BigInteger pubKeyB){
        BigInteger c = g.modPow(signature.w, p).multiply(pubKeyB.modPow(signature.r, p)).mod(p);
        BigInteger h = this.hashq(c, signature.G, signature.M);

        BigInteger lhs1 = (signature.G.multiply(CryptoUtils.pow(pubKeyA, h.add(signature.w)))).mod(p);
        BigInteger rhs1 = g.modPow(signature.d, p);

        BigInteger lhs2 = (signature.M.multiply(CryptoUtils.pow(signature.s, h.add(signature.w)))).mod(p);
        BigInteger rhs2 = m.modPow(signature.d, p);

        System.out.println(lhs1 + " <--> " + rhs1);
        System.out.println(lhs2 + " <--> " + rhs2);

        return lhs1.compareTo(rhs1) == 0 && lhs2.compareTo(rhs2) == 0;
    }

    public JSIDVSSignature simulate(BigInteger pubKeyA, BigInteger priKeyB, BigInteger m){
        JSIDVSSignature signature = new JSIDVSSignature();

        BigInteger d = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
        BigInteger a = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));
        BigInteger b = CryptoUtils.getRandom(BigInteger.valueOf(2), q.subtract(BigInteger.ONE));

        BigInteger s = m.modPow(priKeyB, p);

        BigInteger nb = b.multiply(BigInteger.valueOf(-1));

        BigInteger c = g.modPow(a, p);
        BigInteger G = g.modPow(d, p).multiply(pubKeyA.modPow(nb, p)).mod(p);
        BigInteger M = m.modPow(d, p).multiply(s.modPow(nb, p)).mod(p);
        BigInteger h = this.hashq(c, G, M);
        BigInteger w = (b.subtract(h)).mod(q);
        BigInteger r = ((a.subtract(w)).multiply(BigInteger.ONE.divide(priKeyB))).mod(q);

        signature.s = s;
        signature.w = w;
        signature.r = r;
        signature.G = G;
        signature.M = M;
        signature.d = d;

        return signature;
    }

    private BigInteger hashq(BigInteger c, BigInteger G, BigInteger M){
        BigInteger h = (c.add(G).add(M)).mod(q);
        return h;
    }

    public static class JSIDVSSignature {
        private BigInteger s;
        private BigInteger w;
        private BigInteger r;
        private BigInteger G;
        private BigInteger M;
        private BigInteger d;

        @Override
        public String toString() {
            return "JSIDVSSignature : [\n" +
                    "   s=" + s.toString(RADIX) + ",\n" +
                    "   w=" + w.toString(RADIX) + ",\n" +
                    "   r=" + r.toString(RADIX) + ",\n" +
                    "   G=" + G.toString(RADIX) + ",\n" +
                    "   M=" + M.toString(RADIX) + ",\n" +
                    "   d=" + d.toString(RADIX) + ",\n" +
                    "]";
        }

        public BigInteger getS() {
            return s;
        }

        public void setS(BigInteger s) {
            this.s = s;
        }

        public BigInteger getW() {
            return w;
        }

        public void setW(BigInteger w) {
            this.w = w;
        }

        public BigInteger getR() {
            return r;
        }

        public void setR(BigInteger r) {
            this.r = r;
        }

        public BigInteger getG() {
            return G;
        }

        public void setG(BigInteger g) {
            G = g;
        }

        public BigInteger getM() {
            return M;
        }

        public void setM(BigInteger m) {
            M = m;
        }

        public BigInteger getD() {
            return d;
        }

        public void setD(BigInteger d) {
            this.d = d;
        }
    }

}

и запустить его в main.

package hk.jeff;

import hk.jeff.dvs.JSIDVS;
import hk.jeff.model.KeyPair;

import java.math.BigInteger;

public class App {


    public static void main( String[] args ) throws Exception{
        JSIDVS dvs = new JSIDVS(4);

        System.out.println("JSI Designated Verifier Signature Instance : " + dvs.toString());

        KeyPair keyPairA = dvs.generateKeyPair();
        KeyPair keyPairB = dvs.generateKeyPair();


        System.out.println("keyPairA = " + keyPairA);
        System.out.println("keyPairB = " + keyPairB);

        BigInteger message = new BigInteger("2");

        JSIDVS.JSIDVSSignature signature = dvs.sign(keyPairA.getPrivateKey(), keyPairB.getPublicKey(), message);
        System.out.println("Signature sign by A : " + signature);
        Boolean success = dvs.verify(signature, message, keyPairA.getPublicKey(), keyPairB.getPublicKey());

        System.out.println(success);

    }
}

<span class="math-container">```</span>
...